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:

Java
client.get().uri("/personas/1").accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk() .expectHeader().contentType(MediaType.APPLICATION_JSON);
Kotlin
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.

Java
 client.get().uri("/personas/1") .accept(MediaType.APPLICATION_JSON) .exchange() .expectAll( especificación -> spec.expectStatus().isOk(), especificación -> especificación .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 en List<T>.

  • expectBody(): Decodificación en byte[] para contenido JSON o un contenido vacío body.

Y ejecute aserciones en los objetos de nivel superior resultantes:

Java
 client.get().uri ("/personas") .exchange() .expectStatus().isOk() .expectBodyList(Person.class).hasSize(3).contains(persona);
Kotlin
importar org.springframework.test.web.reactive.server.expectBodyList client.get().uri("/persons" ) .exchange() .expectStatus ().isOk() .expectBodyList<Person>().hasSize(3).contains(persona)

If las aserciones integradas no son suficientes, puede usarlas en su lugar este objeto y ejecutar cualquier otra declaración:

Java
importar org.springframework.test.web. reactivo.servidor.expectBody client.get().uri(" /personas/1") .exchange() .expectStatus().isOk() .expectBody(Person.class) .consumeWith(resultado -> { // afirmaciones especiales (por ejemplo, AssertJ)... });
Kotlin
client.get ( ).uri("/personas/1") .exchange() .expectStatus().isOk() .expectBody<Person>() .consumeWith { // declaraciones especiales (por ejemplo, AssertJ)... }

O puede salir del flujo de trabajo y obtener EntityExchangeResult:

Java
  EntityExchangeResult<Persona> resultado = client.get().uri("/personas/1") .exchange() .expectStatus().isOk() .expectBody(Person.class) .returnResult();
Kotlin
importar org.springframework.test.web.reactive.server.expectBody val result = client.get().uri("/ personas /1") .exchange() .expectStatus().isOk .expectBody<Person>() .returnResult()
Si necesita decodificar al tipo de destino usando genéricos, busque métodos sobrecargados que acepten ParameterizedTypeReference en lugar de Clase<T>.

Sin contenido

Si se espera que la respuesta no tenga contenido, puede confirmarlo de la siguiente manera:

Java
 client.post().uri("/personas") .body(personMono, Person.class) .exchange() .expectStatus().isCreated() .expectBody().isEmpty(); 
Kotlin
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:

Java
client.get().uri("/persons/123") .exchange() .expectStatus(). isNotFound() .expectBody( Void.class);
Kotlin
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:

Java
client.get ().uri("/personas/1") .exchange() .expectStatus().isOk() .expectBody() .json("{\"nombre\": \"Jane\"}") 
Kotlin
client.get().uri("/persons /1") .exchange() .expectStatus( ).isOk() .expectBody() .json("{\"name\":\"Jane\"}")

Para verificar el contenido JSON usando JSONPath:

Java
client.get().uri("/persons") .exchange() .expectStatus().isOk() .expectBody() .jsonPath("$[0]. nombre").isEqualTo("Jane") . jsonPath("$[1].nombre").isEqualTo("Jason");
Kotlin
 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:

Java
FluxExchangeResult<MyEvent> resultado = client.get().uri("/events") .accept(TEXT_EVENT_STREAM) .exchange() .expectStatus().isOk() .returnResult(MyEvent.class);
Kotlin
importar 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:

Java
Flux<Event> eventFlux = resultado.getResponseBody(); StepVerifier.create(eventFlux) .expectNext(persona) .expectNextCount(4) .consumeNextWith(p -> ...) .thenCancel() .verify();
Kotlin
val eventFlux = result.getResponseBody() StepVerifier.create(eventFlux) .expectNext(persona) .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:

Java
// Para una respuesta con cuerpo EntityExchangeResult<Person> resultado = client.get().uri("/personas/1") .exchange() .expectStatus().isOk() .expectBody(Person.class) .returnResult(); // Para una respuesta sin cuerpo EntityExchangeResult<Void> resultado = client.get().uri("/path") .exchange() .expectBody().isEmpty();
Kotlin
// Para una respuesta con un cuerpo val result = client.get().uri("/persons/1") .exchange() .expectStatus().isOk() .expectBody (Persona. clase).returnResult(); // Para una respuesta sin valor de cuerpo result = client.get().uri("/path") .exchange() .expectBody().isEmpty();

Luego cambie a las afirmaciones de respuesta del servidor MockMvc:

Java
MockMvcWebTestClient.resultActionsFor(resultado).andExpect(model().attribute("integer ", 3)).andExpect(model().attribute("cadena", "un valor de cadena"));
Kotlin
            MockMvcWebTestClient.resultActionsFor(resultado) .andExpect(model().attribute("integer", 3))
                .andExpect(model().attribute("cadena", "un valor de cadena")) ;