WebTestClient
надає API-інтерфейс, ідентичний WebClient, аж до виконання запиту
з exchange()
. Приклади підготовки запиту з будь-яким вмістом, включано з даними форми,
багатокомпонентними
даними тощо, див. у документації WebClient.
Після виклику exchange()
WebTestClient
розходиться з WebClient
і натомість
продовжує робочий процес перевірки достовірності відповідей.
Щоб підтвердити статус відповіді та заголовки, використовуй таке:
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON);
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
Якщо потрібно, щоб всі очікувані події були підтверджені, навіть якщо одна з них не спрацювала, то
можна використовувати expectAll(..)
замість кількох послідовних викликів expect*(..)
. Ця
функція схожа на підтримку м'яких тверджень в AssertJ і assertAll()
у JUnit Jupiter.
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectAll(
spec -> spec.expectStatus().isOk(),
spec -> spec.expectHeader().contentType(MediaType.APPLICATION_JSON)
);
Тому можна вибрати декодування тіла відповіді за допомогою одного з наступних способів:
expectBody(Class<T>)
: Декодуємо в один об'єкт.expectBodyList(Class<T>)
: Декодуємо і збираємо об'єкти вList<T>
.expectBody()
: Декодуємо вbyte[]
для вмісту JSON або порожнього тіла.
І виконуємо затвердження на результуючому об'єкті більш високого рівня:
client.get().uri("/persons")
.exchange()
.expectStatus().isOk()
.expectBodyList(Person.class).hasSize(3).contains(person);
import org.springframework.test.web.reactive.server.expectBodyList
client.get().uri("/persons")
.exchange()
.expectStatus().isOk()
.expectBodyList<Person>().hasSize(3).contains(person)
Якщо вбудованих тверджень недостатньо, можна використовувати замість цього об'єкта і виконати будь-які інші твердження:
import org.springframework.test.web.reactive.server.expectBody
client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.consumeWith(result -> {
// special statements (eg AssertJ)...
});
client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody<Person>()
.consumeWith {
// спеціальні твердження (наприклад, AssertJ)...
}
Або можна вийти з робочого процесу і отримати EntityExchangeResult
:
EntityExchangeResult<Person> result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.returnResult();
import org.springframework.test.web.reactive.server.expectBody
val result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk
.expectBody<Person>()
.returnResult()
ParameterizedTypeReference
замість Class<T>
.
Відсутність вмісту
Якщо очікується, що у відповіді не буде вмісту, можна підтвердити це таким чином:
client.post().uri("/persons")
.body(personMono, Person.class)
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty();
client.post().uri("/persons")
.bodyValue(person)
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty()
Якщо потрібно проігнорувати вміст відповіді, то нижче наведено вивільнення вмісту без будь-яких тверджень:
client.get().uri("/persons/123")
.exchange()
.expectStatus().isNotFound()
.expectBody(Void.class);
client.get().uri("/persons/123")
.exchange()
.expectStatus().isNotFound
.expectBody<Unit>()
Вміст JSON
Можна використовувати expectBody()
без цільового типу, щоб
виконувати твердження для неформатованого вмісту, а не робити це через об'єкт(и) вищого рівня.
Щоб перевірити повний вміст JSON з допомогою JSONAssert:
client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.json("{\"name\":\"Jane\"}")
client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.json("{\"name\":\"Jane\"}")
Щоб перевірити вміст JSON за допомогою JSONPath:
client.get().uri("/persons")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[0].name").isEqualTo("Jane")
.jsonPath("$[1].name").isEqualTo("Jason");
client.get().uri("/persons")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[0].name").isEqualTo("Jane")
.jsonPath("$[1].name").isEqualTo("Jason")
Потокові відповіді
Щоб перевірити потенційно нескінченні потоки, такі як
"text/event-stream"
або "application/x-ndjson"
, почни з перевірки статусу та заголовків
відповіді, а потім отримай FluxExchangeResult
:
FluxExchangeResult<MyEvent> result = client.get().uri("/events")
.accept(TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.returnResult(MyEvent.class);
import org.springframework.test.web.reactive.server.returnResult
val result = client.get().uri("/events")
.accept(TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.returnResult<MyEvent>()
Тепер ти готовий споживати потік відповідей за допомогою StepVerifier
з reactor-test
:
Flux<Event> eventFlux = result.getResponseBody();
StepVerifier.create(eventFlux)
.expectNext(person)
.expectNextCount(4)
.consumeNextWith(p -> ...)
.thenCancel()
.verify();
val eventFlux = result.getResponseBody()
StepVerifier.create(eventFlux)
.expectNext(person)
.expectNextCount(4)
.consumeNextWith { p -> ... }
.thenCancel()
.verify()
Твердження MockMvc
WebTestClient
— це HTTP-клієнт, тому він може перевіряти тільки те,
що знаходиться у відповіді клієнта, включно зі статусом, заголовками та тілом. Для цього почни з отримання ExchangeResult
після додавання затвердження до тіла:
// Для відповіді з тілом
EntityExchangeResult<Person> result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.returnResult();
// Для відповіді без тіла
EntityExchangeResult<Void> result = client.get().uri("/path")
.exchange()
.expectBody().isEmpty();
// Для відповіді з тілом
val result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.returnResult();
// Для відповіді без тіла
val result = client.get().uri("/path")
.exchange()
.expectBody().isEmpty();
Потім перейди на затвердження відповіді сервера MockMvc:
MockMvcWebTestClient.resultActionsFor(result)
.andExpect(model().attribute("integer", 3))
.andExpect(model().attribute("string", "a string value"));
MockMvcWebTestClient.resultActionsFor(result)
.andExpect(model().attribute("integer", 3))
.andExpect(model().attribute("string", "a string value"));
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ