В этой статье показаны самые простые примеры использования библиотеки REST-assured.
Что тестируем
Тестировать будем простое Spring Boot приложение — то же, что и в предыдущей статье о TestRestTemplate. Приложение предоставляет RESTfull API для сущности Person:
@Entity
public class Person {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  @NotNull
  private String name;
        // setters/getters        
}
Подробнее о создании приложение читайте в руководстве. Сразу скажу, что в приложении мы используем встроенную базу h2 db, чтобы не устанавливать внешнюю базу данных.
Базу мы очищаем после каждого теста, чтобы все было понятно — каждый тест начинается с пустой базы, в которую при необходимости мы добавляем одного или двоих Person.
Maven-зависимость
Чтобы использовать библиотеку REST-assured, включите в проект зависимость:
<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>3.1.0</version>
      <scope>test</scope>
</dependency>
Последняя версия доступна здесь.
Тестирование добавления — POST
Запись в базу мы добавляем с мопощью такого POST-запроса:
POST /persons
При этом в теле передается Person в формате JSON:
{
    "id": null,
    "name": "Michail"
}
В ответ мы должны получить вновь созданного Person в формате JSON и статус 201 (created).
Протестируем и убедимся, что все так и есть:
@Test
public void whenCreatePerson_thenStatus201() {
    Person person = new Person("Michail");
    
    given().log().body()
    .contentType("application/json").body(person)
    
    .when().post("/persons")
    
    .then().log().body()
    .statusCode(HttpStatus.CREATED.value());
}
given(), when() и then()
Тест REST-assured состоит из трех частей:
- given() задает предварительные условия запроса. Здесь это content-type (мы задали формат JSON), логирование и тело запроса.
 Логирование мы включили для учебных целей. Благодаря log().body() мы увидим в консоли тело посланного запроса.
 Тело запроса задано в методе body(person). То есть в теле будет Person в JSON-формате.
 Вообще часть given() необязательна, но чаще она есть.
- when() — тут мы говорим, что это POST-запрос по адресу /persons
- then() — тут происходит само тестирование.
 Мы снова логируем, но уже тело ответа.
 И проверяем, что код ответа равен 201.
Тестирование редактирования — PUT
Следующий запрос — для редактирования Person:
PUT /persons/{id}
В теле запроса снова передается Person в формате JSON с заданным id:
{
    "id": 1,
    "name": "Michail"
}
Тестирование выглядит так (в начале теста мы создаем тестовый Person и берем его id, чтоб отредактировать сущность по адресу /persons/{id}:
@Test
public void whenUpdatePerson_thenStatus200() {
	long id = createTestPerson("Nick").getId();
	Person person = new Person("Michail");
	given().pathParam("id", id).log()
        .body().contentType("application/json").body(person)
        
        .when().put("/persons/{id}")
        
        .then().log().body().statusCode(HttpStatus.OK.value())
               .and().body("name", equalTo("Michail"));
}
Тут присутствует метод pathParam(«id», id) — на место id в пути /persons/id мы подставляем реальное значение id того Person, которого мы хотим отредактировать.
Также мы тестируем тело JSON-ответа — проверяем, что name действительно равно Michail.
Тестирование удаления — DELETE
Запрос выглядит так:
DELETE /persons/{id}
В теле запроса ничего не передается.
Возвращается JSON удаленного Person:
{
    "id": 1,
    "name": "Nick"
}
Протестируем. В начале метода мы снова создаем Person, которого будем удалять, и берем его id:
@Test
public void givenPerson_whenDeletePerson_thenStatus200() {
	long id = createTestPerson("Nick").getId();
	
        given().pathParam("id",  id).log().body().contentType("application/json")
        
       .when().delete("/persons/{id}")
        
       .then().log().body()
           .statusCode(HttpStatus.OK.value()).and().body("name", equalTo("Nick"));
}
Мы логируем тело ответа и проверяем, что его имя равно Nick.
Еще, как обычно, проверяем код ответа.
Тестирование получения — GET
GET /persons
Здесь ничего нового, единственное — метод get():
@Test
public void givenPerson_whenGetPerson_thenStatus200() {
	long id = createTestPerson("Joe").getId();
	given().pathParam("id", id)
		
	.when().get("/persons/{id}")
		
	.then().log().body().statusCode(HttpStatus.OK.value())
				.and().body("name", equalTo("Joe"));
}
А теперь попробуем получить Person, которого не существует. Для этого просто не создаем его в начале метода, ведь база пуста:
@Test
public void givenNoPerson_whenGetPerson_thenStatus500() {
	given().pathParam("id", 1)
        .when().get("/persons/{id}")
          
        .then().log().body()
               .statusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
По умолчанию Spring выдает код ответа 500, так как контроллер выбрасывает исключение, которое мы в приложении никак не обрабатываем. Действительно, мы получили код ответа 500.
Тестирование получения списка — GET
GET /persons
[
    {
        "id": 1,
        "name": "Joe"
    },
    {
        "id": 2,
        "name": "Jane"
    }
]
В начале теста создадим два элемента.
Проверим, что при запросе списка возвращается код ответа 200, и каждый элемент имеет соответствующее имя:
@Test
public void givenPersons_whenGetPersons_thenStatus200() {
	createTestPerson("Joe");
	createTestPerson("Jane");
	when().get("/persons")
	
        .then().log().body()
	.statusCode(HttpStatus.OK.value())
	.and().body("get(0).name", equalTo("Joe"))
	.and().body("get(1).name", equalTo("Jane"));
}
Обратите внимание, что для получения элементов списка используются команды get(0), get(1)
Итог
REST-assured — удобная библиотека, ее стоит использовать.
Исходный код проекта находится на GitHub.