WebTestClient
proporciona una API idéntica a WebClient, hasta la ejecución de la solicitud con usando exchange()
. Para ver ejemplos de cómo preparar una solicitud con cualquier contenido, incluidos datos de formulario, datos de varias partes y más, consulte la documentación de WebClient.
Después de llamar a exchange()
, WebTestClient
diverge de WebClient
y en su lugar continúa la respuesta. Flujo de trabajo de validación.
Para confirmar el estado de la respuesta y los encabezados, utilice lo siguiente:
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)
Si desea que se reconozcan todos los eventos esperados, incluso si uno de ellos falla, puede utilice expectAll(..)
en lugar de varias llamadas consecutivas a expect*(..)
. Esta característica es similar a la compatibilidad con aserciones suaves en AssertJ y assertAll()
en JUnit Jupiter.
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectAll(
spec -> spec.expectStatus().isOk(),
spec -> spec.expectHeader().contentType(MediaType.APPLICATION_JSON)
);
Luego puede optar por decodificar el cuerpo de la respuesta utilizando uno de los siguientes métodos:
expectBody(Class<T>)
: Decodificación en un objeto.expectBodyList(Class<T>)
: Decodificar y recopilar objetos enList<T>
.expectBody()
: Decodificación enbyte[]
para contenido JSON o un contenido vacío body.
Y ejecute aserciones en los objetos de nivel superior resultantes:
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)
If las aserciones integradas no son suficientes, puede usarlas en su lugar este objeto y ejecutar cualquier otra declaración:
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 {
// special statements (eg AssertJ)...
}
O puede salir del flujo de trabajo y obtener 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
en lugar de
Clase<T>
.
Sin contenido
Si se espera que la respuesta no tenga contenido, puede confirmarlo de la siguiente manera:
client.post().uri("/persons")
.body(personMono, Person.class)
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty();
client.post().uri("/persons")
.bodyValue(person)
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty()
Si desea ignorar el contenido de la respuesta, a continuación se muestra el comunicado del contenido sin aserciones:
client.get().uri("/persons/123")
.exchange()
.expectStatus().isNotFound()
.expectBody(Void.class);
client.get().uri("/persons/123")
.exchange()
.expectStatus().isNotFound
.expectBody<Unit>()
Contenido JSON
Puedes usar expectBody()
sin un tipo de destino para hacer afirmaciones sobre contenido sin formato, en lugar de tener que hacerlo a través de objetos de nivel superior.
Para examinar el contenido JSON completo usando 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\"}")
Para verificar el contenido JSON usando 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")
Transmitir respuestas
Para comprobar secuencias potencialmente infinitas, como "text/event-stream"
o "application/x-ndjson"
, comience comprobando la respuesta estado y encabezados, y luego obtenga 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>()
Ahora está listo para consumir el flujo de respuesta usando StepVerifier
de 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()
Aserciones de MockMvc
WebTestClient
es HTTP cliente, por lo que solo puede verificar lo que hay en la respuesta del cliente, incluido el estado, los encabezados y el cuerpo.
Al probar una aplicación Spring MVC con una configuración de servidor MockMvc, tiene la capacidad adicional de realizar más afirmaciones en la respuesta del servidor. Para hacer esto, comience obteniendo el ExchangeResult
después de agregar la afirmación al cuerpo:
// Para una respuesta con cuerpo
EntityExchangeResult<Person> result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.returnResult();
// Para una respuesta sin cuerpo
EntityExchangeResult<Void> result = client.get().uri("/path")
.exchange()
.expectBody().isEmpty();
// Para una respuesta con un cuerpo
val result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.returnResult();
// Para una respuesta sin valor de cuerpo
val result = client.get().uri("/path")
.exchange()
.expectBody().isEmpty();;
Luego cambie a las afirmaciones de respuesta del servidor 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"));
GO TO FULL VERSION