Перейти к основному содержимому

Получение и проверка данных ответа с гарантией REST

· 5 мин. чтения

1. Обзор

В этом руководстве мы обсудим, как тестировать службы REST с помощью REST-assured, уделяя особое внимание сбору и проверке данных ответов от наших API-интерфейсов REST .

2. Подготовка к тестовому классу

В предыдущих руководствах мы рассмотрели REST-assured в целом и показали, как манипулировать заголовками запросов, файлами cookie и параметрами .

Опираясь на эту существующую настройку, мы добавили простой контроллер REST, AppController , который внутренне вызывает службу AppService . Мы будем использовать эти классы в наших тестовых примерах.

Чтобы создать наш тестовый класс, нам нужно немного больше настроить. Поскольку у нас есть spring-boot-starter-test в нашем пути к классам, мы можем легко использовать утилиты тестирования Spring.

Во-первых, давайте создадим скелет нашего класса AppControllerIntegrationTest :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class AppControllerIntegrationTest {

@LocalServerPort
private int port;

private String uri;

@PostConstruct
public void init() {
uri = "http://localhost:" + port;
}

@MockBean
AppService appService;

//test cases
}

В этом тесте JUnit мы аннотировали наш класс парой специфичных для Spring аннотаций, которые запускают приложение локально в случайном доступном порту. В @PostConstruct мы зафиксировали полный URI, по которому будем выполнять вызовы REST.

Мы также использовали @MockBean в AppService , так как нам нужно имитировать вызовы методов этого класса.

3. Проверка ответа JSON

JSON — это наиболее распространенный формат, используемый в REST API для обмена данными. Ответы могут состоять из одного объекта JSON или массива объектов JSON. Мы рассмотрим оба в этом разделе.

3.1. Один объект JSON

Допустим, нам нужно протестировать конечную точку /movie/{id} , которая возвращает объект Movie JSON, если идентификатор найден.

Мы будем имитировать вызовы AppService , чтобы вернуть некоторые фиктивные данные, используя фреймворк Mockito :

@Test
public void givenMovieId_whenMakingGetRequestToMovieEndpoint_thenReturnMovie() {

Movie testMovie = new Movie(1, "movie1", "summary1");
when(appService.findMovie(1)).thenReturn(testMovie);

get(uri + "/movie/" + testMovie.getId()).then()
.assertThat()
.statusCode(HttpStatus.OK.value())
.body("id", equalTo(testMovie.getId()))
.body("name", equalTo(testMovie.getName()))
.body("synopsis", notNullValue());
}

Выше мы сначала смоделировали вызов appService.findMovie(1) для возврата объекта. Затем мы создали наш URL-адрес REST в методе get() , предоставленном REST-assured для выполнения запросов GET. Наконец, мы сделали четыре утверждения.

Сначала мы проверили код состояния ответа, а затем элементы тела . Мы используем Hamcrest для утверждения ожидаемого значения.

Также обратите внимание, что если ответ JSON является вложенным, мы можем протестировать вложенный ключ, используя оператор точки , например «key1.key2.key3» .

3.2. Извлечение ответа JSON после проверки

В некоторых случаях нам может понадобиться извлечь ответ после проверки, чтобы выполнить над ним дополнительные операции.

Мы можем извлечь ответ JSON для класса, используя метод extract() :

Movie result = get(uri + "/movie/" + testMovie.getId()).then()
.assertThat()
.statusCode(HttpStatus.OK.value())
.extract()
.as(Movie.class);
assertThat(result).isEqualTo(testMovie);

В этом примере мы указали REST-assured для извлечения ответа JSON на объект Movie , а затем утвердили извлеченный объект.

Мы также можем извлечь весь ответ на строку, используя API extract().asString() :

String responseString = get(uri + "/movie/" + testMovie.getId()).then()
.assertThat()
.statusCode(HttpStatus.OK.value())
.extract()
.asString();
assertThat(responseString).isNotEmpty();

Наконец, мы можем также извлечь конкретное поле из ответа JSON .

Давайте посмотрим на тест для POST API, который ожидает тело фильма в формате JSON и возвращает его при успешной вставке:

@Test
public void givenMovie_whenMakingPostRequestToMovieEndpoint_thenCorrect() {
Map<String, String> request = new HashMap<>();
request.put("id", "11");
request.put("name", "movie1");
request.put("synopsis", "summary1");

int movieId = given().contentType("application/json")
.body(request)
.when()
.post(uri + "/movie")
.then()
.assertThat()
.statusCode(HttpStatus.CREATED.value())
.extract()
.path("id");
assertThat(movieId).isEqualTo(11);
}

Выше мы сначала сделали объект запроса, который нам нужно отправить. Затем мы извлекли поле id из возвращенного ответа JSON, используя метод path() .

3.3. JSON-массив

Мы также можем проверить ответ, если это массив JSON:

@Test
public void whenCallingMoviesEndpoint_thenReturnAllMovies() {

Set<Movie> movieSet = new HashSet<>();
movieSet.add(new Movie(1, "movie1", "summary1"));
movieSet.add(new Movie(2, "movie2", "summary2"));
when(appService.getAll()).thenReturn(movieSet);

get(uri + "/movies").then()
.statusCode(HttpStatus.OK.value())
.assertThat()
.body("size()", is(2));
}

Мы снова сначала смоделировали appService.getAll() с некоторыми данными и сделали запрос к нашей конечной точке. Затем мы утвердили statusCode и размер нашего массива ответов.

Это снова можно сделать с помощью извлечения:

Movie[] movies = get(uri + "/movies").then()
.statusCode(200)
.extract()
.as(Movie[].class);
assertThat(movies.length).isEqualTo(2);

Мы можем проверить заголовок или файл cookie ответа, используя методы с тем же именем:

@Test
public void whenCallingWelcomeEndpoint_thenCorrect() {
get(uri + "/welcome").then()
.assertThat()
.header("sessionId", notNullValue())
.cookie("token", notNullValue());
}

Мы также можем извлечь заголовки и файлы cookie по отдельности:

Response response = get(uri + "/welcome");

String headerName = response.getHeader("sessionId");
String cookieValue = response.getCookie("token");
assertThat(headerName).isNotBlank();
assertThat(cookieValue).isNotBlank();

5. Проверка файлов

Если наш REST API возвращает файл, мы можем использовать метод asByteArray() для извлечения ответа:

File file = new ClassPathResource("test.txt").getFile();
long fileSize = file.length();
when(appService.getFile(1)).thenReturn(file);

byte[] result = get(uri + "/download/1").asByteArray();

assertThat(result.length).isEqualTo(fileSize);

Здесь мы сначала издевались над appService.getFile(1) , чтобы вернуть текстовый файл, который присутствует в нашем пути src/test/resources . Затем мы сделали вызов нашей конечной точке и извлекли ответ в byte[] , который, как мы утверждали, имеет ожидаемое значение.

6. Заключение

В этом руководстве мы рассмотрели различные способы сбора и проверки ответов от наших REST API с использованием REST-assured.

Как обычно, код из этой статьи доступен на Github .