Prueba el resorte El marco de prueba MVC, también conocido como MockMvc, proporciona soporte para probar aplicaciones Spring MVC. Realiza el procesamiento completo de solicitudes Spring MVC a través de objetos simulados de solicitud y respuesta en lugar de un servidor en ejecución.

MockMvc se puede usar por separado para realizar solicitudes y validar respuestas. También se puede utilizar a través de WebTestClient, donde MockMvc está conectado como servidor para procesar solicitudes. La ventaja de WebTestClient es la capacidad de trabajar con objetos de nivel superior en lugar de datos sin procesar, y la capacidad de pasar a pruebas HTTP completas de un extremo a otro en un servidor real utilizando la misma API de prueba.

Breve descripción

Puedes escribir pruebas unitarias simples para Spring MVC creando una instancia de un controlador, agregándole dependencias y llamando a sus métodos. Sin embargo, dichas pruebas no verifican las asignaciones de solicitudes, el enlace de datos, la conversión de mensajes, la conversión de tipos, la validación y no utilizan ninguno de los métodos auxiliares anotados con @InitBinder, @ModelAttribute, o @ExceptionHandler.

El marco de prueba Spring MVC, también conocido como MockMvc, tiene como objetivo proporcionar pruebas más completas de los controladores Spring MVC sin un servidor en ejecución. Para ello, llama a DispatcherServlet y pasa implementaciones simuladas de API de servlet desde el módulo spring-test, que reproduce el procesamiento completo de las solicitudes Spring MVC sin un servidor en ejecución.

MockMvc es un marco de prueba del lado del servidor que le permite probar la mayoría de los Funcionalidad de una aplicación Spring MVC que utiliza pruebas ligeras y específicas. Puede usarlo por separado para realizar solicitudes y verificar respuestas, o puede usarlo a través de la API WebTestClient con MockMvc conectado como servidor para procesar solicitudes.

Importación estática

Cuando utilice MockMvc directamente para ejecutar solicitudes, deberá realizar una importación estática:

  • MockMvcBuilders.*

  • MockMvcRequestBuilders.*

  • MockMvcResultMatchers.*

  • MockMvcResultHandlers.*

Una manera fácil de recordarlos es buscar MockMvc*. Si está utilizando Eclipse, asegúrese de agregar también los miembros estáticos anteriores a sus "favoritos" en las preferencias de Eclipse.

Cuando utilice MockMvc a través de WebTestClient, no necesitará importación estática. WebTestClient proporciona una API fluida sin importación estática.

Opciones de configuración

MockMvc puede ser configurado de dos maneras. Una es apuntar directamente a los controladores que deben probarse y configurar mediante programación el marco Spring MVC. El segundo es señalar la configuración de Spring cuando se utiliza el marco Spring MVC y el marco del controlador dentro de él.

Para configurar MockMvc para probar un controlador específico, use lo siguiente:

Java

          class MyWebTests {
    MockMvc mockMvc;
    @BeforeEach
    void setup() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
    }
    // ...
}
Kotlin

class MyWebTests {
    lateinit var mockMvc : MockMvc
    @BeforeEach
    fun setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(AccountController()).build()
    }
    // ...
}

O también puedes usar esta configuración al realizar pruebas a través de WebTestClient, que delega autoridad a la misma herramienta de compilación, como se muestra arriba.

Para configurar MockMvc a través de la configuración de Spring, use lo siguiente:

Java

@SpringJUnitWebConfig(locations = "my-servlet-context.xml")
class MyWebTests {
    MockMvc mockMvc;
    @BeforeEach
    void setup(WebApplicationContext wac) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }
    // ...
}
Kotlin

@SpringJUnitWebConfig(locations = ["my-servlet-context.xml"])
class MyWebTests {
    lateinit var mockMvc: MockMvc
    @BeforeEach
    fun setup(wac: WebApplicationContext) {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
    }
    // ...
}

O también puede utilizar esta configuración al realizar pruebas a través de WebTestClient, que delega autoridad a la misma herramienta de compilación que se muestra arriba.

¿Qué opción de configuración debería utilizar?

webAppContextSetup carga la configuración real de Spring MVC, lo que permite una prueba de integración más completa. Debido a que el marco TestContext almacena en caché la configuración de Spring cargada, le ayuda a ejecutar pruebas rápidamente incluso cuando introduce más pruebas en su conjunto de pruebas. Además, puede inyectar servicios simulados en los controladores utilizando la configuración de Spring para centrarse en las pruebas de nivel web. En el siguiente ejemplo, el servicio simulado se declara usando Mockito:


<bean id="accountService" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="org.example.AccountService"/>
</bean>

Luego puede inyectar el servicio simulado en una prueba para configurar y probar los eventos esperados, como se muestra en el siguiente ejemplo:

Java

@SpringJUnitWebConfig(locations = "test-servlet-context.xml")
class AccountTests {
    @Autowired
    AccountService accountService;
    MockMvc mockMvc;
    @BeforeEach
    void setup(WebApplicationContext wac) {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }
    // ...
}
Kotlin

@SpringJUnitWebConfig(locations = ["test-servlet-context.xml"])
class AccountTests {
    @Autowired
    lateinit var accountService: AccountService
    lateinit mockMvc: MockMvc
    @BeforeEach
    fun setup(wac: WebApplicationContext) {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
    }
    // ...
}

La configuración standaloneSetup, por otro lado, es un poco más adecuada para pruebas unitarias. Ella prueba un controlador a la vez. Es posible inyectar manualmente dependencias simuladas en el controlador sin necesidad de cargar la configuración de Spring. Estas pruebas están más orientadas al estilo y le permiten comprender qué controlador se está probando, si se requiere alguna configuración Spring MVC específica para funcionar, etc. Configurar standaloneSetup también es una forma muy conveniente de escribir pruebas personalizadas para probar una lógica específica o depurar un problema.

Como ocurre con la mayoría de los debates sobre pruebas de integración versus pruebas unitarias, existen No hay respuesta correcta o incorrecta. Sin embargo, usar standaloneSetup implica la necesidad de realizar pruebas adicionales usando webAppContextSetup para validar la configuración de Spring MVC. Además, puede escribir todas sus pruebas usando webAppContextSetup para probar siempre con una configuración real de Spring MVC.

Funciones de configuración

No importa qué herramienta Ensamblajes de MockMvc que utilice, todas las implementaciones de MockMvcBuilder proporcionarán algunas funciones comunes y extremadamente útiles. Por ejemplo, podría declarar un encabezado Aceptar en todas las solicitudes y aceptar el estado 200, así como un encabezado Content-Type en todas las respuestas, como se muestra a continuación:

Java

// importación estática MockMvcBuilders.standaloneSetup
MockMvc mockMvc = standaloneSetup(new MusicController())
    .defaultRequest(get("/").accept(MediaType.APPLICATION_JSON))
    .alwaysExpect(status().isOk())
    .alwaysExpect(content().contentType("application/json;charset=UTF-8"))
    .build();
Kotlin
// No es posible en
            Kotlin hasta está arreglado

Además, los marcos (y aplicaciones) de terceros pueden empaquetar previamente instrucciones de configuración, por ejemplo en MockMvcConfigurer. Spring Framework tiene una implementación incorporada que ayuda a guardar y reutilizar la sesión HTTP en todas las solicitudes. Puedes usarlo así:

Java

// importación estática SharedHttpSessionConfigurer.sharedHttpSession
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
    .apply(sharedHttpSession())
    .build();
// Importa mockMvc para ejecutar consultas...
Kotlin
// No es posible en Kotlin hasta no se solucionará

Ver. javadoc por ConfigurableMockMvcBuilder para obtener una lista de todas las capacidades del generador MockMvc, o use el IDE para explorar las opciones disponibles.

Ejecución de consultas

En esta sección se muestra cómo usar MockMvc por separado para realizar solicitudes y validar respuestas. Si está utilizando MockMvc a través de WebTestClient, consulte la sección correspondiente en escribiendo pruebas.

Para ejecutar solicitudes utilizando cualquier método HTTP, confíe en el ejemplo que se muestra a continuación:

Java

// importación estática MockMvcRequestBuilders.*. 
mockMvc.perform(post("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON));
Kotlin

import org.springframework.test.web.servlet.post
mockMvc.post("/hotels/{id}", 42) {
    accept = MediaType.APPLICATION_JSON
}

También es posible realizar solicitudes de carga de archivos que utilicen internamente MockMultipartHttpServletRequest para evitar analizar la solicitud de varias partes. Más bien, tendrás que configurarlo como se muestra en el siguiente ejemplo:

Java
mockMvc.perform(multipart("/doc").file("a1 " , "ABC".getBytes("UTF-8")));
Kotlin

import org.springframework.test.web.servlet.multipart
mockMvc.multipart("/doc") {
    file("a1", "ABC".toByteArray(charset("UTF8")))
}

Puede especificar parámetros de solicitud en el estilo de patrón URI, como se muestra en el siguiente ejemplo:

Java
mockMvc.perform(get ("/hotels?thing={thing}", "somewhere"));
Kotlin
mockMvc .get("/hotels?thing={thing}", "somewhere")

También puede agregar parámetros de solicitud de servlet, que son solicitudes parámetros, o parámetros de formulario, como se muestra en el siguiente ejemplo:

Java
mockMvc.perform(get("/hotels").param("thing", " somewhere"));
Kotlin

import org.springframework.test.web.servlet.get
mockMvc.get("/hotels") {
    param("thing", "somewhere")
}

Si el código de la aplicación utiliza parámetros de solicitud de servlet y no verifique la cadena de consulta explícitamente (que es lo que sucede con mayor frecuencia), entonces no importa qué opción use. Sin embargo, tenga en cuenta que los parámetros de solicitud proporcionados mediante el patrón URI se decodifican, mientras que se espera que los parámetros de solicitud proporcionados mediante el método param(...) ya estén decodificados.

En en la mayoría de los casos, es preferible omitir la ruta de contexto y la ruta del servlet del URI de solicitud. Si necesita realizar la prueba con el URI de solicitud completo, asegúrese de configurar contextPath y servletPath de manera adecuada para que la coincidencia de solicitudes funcione, como se muestra en el siguiente ejemplo:

Java

mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath("/main"))
Kotlin

import org.springframework.test.web.servlet.get
mockMvc.get("/ app/main/hotels/{id}") {
    contextPath = "/app"
    servletPath = "/main"
}

En el ejemplo anterior, No será conveniente configurar contextPath y servletPath en cada solicitud realizada. En su lugar, puede establecer propiedades de consulta predeterminadas, como se muestra en el siguiente ejemplo:

Java

class MyWebTests {
    MockMvc mockMvc;
    @BeforeEach
    void setup() {
        mockMvc = standaloneSetup(new AccountController())
            .defaultRequest(get("/")
            .contextPath("/app").servletPath("/main")
            .accept(MediaType.APPLICATION_JSON)).build();
    }
}
Kotlin
// No es posible en Kotlin hasta no se solucionará

Las propiedades anteriores afectan a cada solicitud realizada a través del instancia MockMvc. Si también se especifica la misma propiedad en una solicitud determinada, anula el valor predeterminado. Por lo tanto, el método HTTP predeterminado y el URI en la solicitud son irrelevantes porque deben especificarse para cada solicitud.

Definición de eventos esperados

Puede definir eventos esperados agregando una o varias llamadas a andExpect(..) después de que se haya completado la solicitud, como se muestra en el siguiente ejemplo. Si algún evento esperado no ocurre, otros eventos esperados no se confirmarán.

Java

// importación estática MockMvcRequestBuilders.*. y MockMvcResultMatchers.* 
mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());
Kotlin

import org.springframework.test.web.servlet.get
mockMvc.get("/accounts/1").andExpect {
    status { isOk() }
}

Puede definir varios eventos esperados agregando andExpectAll(..) después de ejecutar la solicitud, como se muestra en el siguiente ejemplo. A diferencia de andExpect(..), andExpectAll(..) garantiza que todos los eventos esperados especificados se confirmen y que cualquier evento fallido se supervise y se informe.

Java

// importación estática MockMvcRequestBuilders.*. y MockMvcResultMatchers.*
mockMvc.perform(get("/accounts/1")).andExpectAll(
    status().isOk(),
    content().contentType("application/json;charset=UTF-8"));;

MockMvcResultMatchers.* especifica una serie de eventos esperados, algunos de los cuales están anidados dentro de eventos esperados más detallados.

Los eventos esperados se dividen en dos categorías generales. La primera categoría de aserciones verifica las propiedades de la respuesta (como el estado de la respuesta, los encabezados y el contenido). Estos son los resultados más importantes que se pueden respaldar.

La segunda categoría de afirmaciones va más allá del alcance de la respuesta. Estas afirmaciones le permiten verificar aspectos específicos de Spring MVC, como qué método de controlador manejó la solicitud, si se lanzó y manejó una excepción, cuál es el contenido del modelo, qué vista se seleccionó, qué atributos flash se agregaron, etc. en. También le permiten probar aspectos específicos de los servlets, como los atributos de solicitud y sesión.

La siguiente prueba confirma que el enlace o la validación fallaron:

Java

mockMvc.perform(post("/persons"))
    .andExpect(status().isOk())
    .andExpect(model().attributeHasErrors("person"));
Kotlin

import org.springframework.test.web.servlet.post
mockMvc.post("/persons").andExpect {
    status { isOk() }
    model {
        attributeHasErrors("person")
    }
}

A menudo, al escribir pruebas, es útil descargar los resultados de la consulta ejecutada. Esto se puede hacer de la siguiente manera, donde print() es un elemento estático importado de MockMvcResultHandlers:

Java

mockMvc.perform(post("/persons"))
    .andDo(print())
    .andExpect(status().isOk())
    .andExpect(model().attributeHasErrors("person")); 
Kotlin

import org.springframework.test.web.servlet.post
mockMvc.post("/persons").andDo {
        print()
    }.andExpect {
        status { isOk() }
        model {
            attributeHasErrors("person")
        }
            }

Siempre que el La solicitud se procesa no generará una excepción no controlada, el método print() generará todos los datos de resultados disponibles en System.out. También hay un método log() y dos variantes adicionales del método print(), uno de los cuales toma un OutputStream y el otro toma un Escritor . Por ejemplo, llamar a print(System.err) genera los datos del resultado en System.err y llamar a print(myWriter) genera los datos del resultado. a un método especial de registros (escritor). Si desea que los datos del resultado se registren en lugar de imprimirse, puede llamar al método log(), que escribe los datos del resultado como un único mensaje DEBUG en la categoría de registro. org.springframework.test.web.servlet.result.

En algunos casos, es posible que desee acceder directamente al resultado y probar algo que no se puede probar de ninguna otra manera. Esto se puede lograr agregando .andReturn() después de todos los demás eventos esperados, como se muestra en el siguiente ejemplo:

Java
 
MvcResult mvcResult = mockMvc.perform(post("/personas")).andExpect(status().isOk()).andReturn(); 
// ...
Kotlin

var mvcResult = mockMvc.post("/persons").andExpect { status { isOk() } }.andReturn()
// ...

Si todas las pruebas repiten los mismos eventos esperados, entonces puede establecer valores comunes eventos esperados una vez al crear una instancia de MockMvc, como se muestra en el siguiente ejemplo:

Java

standaloneSetup(new SimpleController())
    .alwaysExpect(status().isOk())
    .alwaysExpect(content().contentType("application/json;charset=UTF-8"))
    .build()
Kotlin
// No es posible en Kotlin hasta
        que se solucione 

Tenga en cuenta que los eventos esperados genéricos siempre se aplican y no se pueden anular sin crear una instancia separada de MockMvc.

Si el contenido de la respuesta JSON contiene enlaces hipermedia creados usando Spring HATEOAS, puede validar los enlaces resultantes utilizan expresiones JsonPath, como se muestra en el siguiente ejemplo:

Java

mockMvc.perform(get("/people").accept (MediaType.APPLICATION_JSON))
    .andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("http://localhost:8080/people"));
Kotlin

mockMvc.get("/people") {
    accept(MediaType.APPLICATION_JSON)
}.andExpect {
    jsonPath("$.links[?(@.rel == 'self')].href") {
        value("http://localhost:8080/people")
    }
}

Si el contenido de la respuesta XML contiene enlaces hipermedia creados usando Spring HATEOAS , usted Puede comprobar los enlaces recibidos utilizando expresiones XPath:

Java

Map<String, String> ns = Collections.singletonMap("ns", "http://www.w3.org/2005/Atom");
mockMvc.perform(get("/handle").accept(MediaType.APPLICATION_XML))
    .andExpect(xpath("/person/ns:link[@rel='self']/@href", ns).string("http://localhost:8080/people"));
Kotlin

val ns = mapOf("ns" to "http://www.w3.org/2005/Atom")
mockMvc.get("/handle") {
    accept(MediaType.APPLICATION_XML)
}.andExpect {
    xpath("/person/ns:link[@rel='self']/@href", ns) {
        string("http://localhost:8080/people")
    }
}

Asincrónico request

Esta sección muestra cómo usar MockMvc por separado para probar el procesamiento de solicitudes asincrónicas. Cuando se utiliza MockMvc a través de WebTestClient, no hay nada especial en hacer que funcionen las solicitudes asincrónicas, ya que WebTestClient hace automáticamente lo que se describe en esta sección.

Async Servlet 3.0 Las solicitudes, compatibles con Spring MVC, funcionan saliendo del subproceso del contenedor de servlets, por lo que permitiendo que la aplicación evalúe la respuesta de forma asincrónica, después de lo cual se realiza el envío asincrónico para completar el procesamiento en el subproceso del contenedor de servlet.

En Spring MVC Test, las solicitudes asincrónicas se pueden probar afirmando primero el valor asincrónico generado y luego realizar manualmente el envío asincrónico y finalmente verificar la respuesta. A continuación se muestra una prueba de ejemplo para métodos de controlador que devuelven DeferredResult, Callable o un tipo reactivo como Mono de Reactor:

Java

// importación estática MockMvcRequestBuilders.*. y MockMvcResultMatchers.*
@Test
void test() throws Exception {
    MvcResult mvcResult = this.mockMvc.perform(get("/path"))
            .andExpect(status().isOk()) 
            .andExpect(request().asyncStarted()) 
            .andExpect(request() .asyncResult("body")) 
            .andReturn();
    this.mockMvc.perform(asyncDispatch(mvcResult)) 
            .andExpect(status().isOk()) 
            .andExpect(content().string("body")); }
  1. El estado de verificación de respuesta permanece sin cambios
  2. El procesamiento asincrónico debe comenzar
  3. Esperamos y confirmamos el resultado del procesamiento asincrónico
  4. Realizamos manualmente el envío asincrónico (ya que no hay ningún contenedor en ejecución)
  5. Verificamos la respuesta final
Kotlin

@Test
fun test() {
    var mvcResult = mockMvc.get("/path").andExpect {
        status { isOk() } 
        request { asyncStarted() } 
        // TODO Eliminar genérico no utilizado solicitud de parámetro request { asyncResult<Nothing> ("body") } 
    }.andReturn()
    mockMvc.perform(asyncDispatch(mvcResult)) 
            .andExpect {
                status { isOk() } 
                content().string("body ")
            }
}
  1. El estado de verificación de respuesta permanece sin cambios
  2. Procesamiento asincrónico
  3. Esperamos y confirmamos el resultado del procesamiento asincrónico
  4. Realizamos manualmente el envío asincrónico (ya que no hay ningún contenedor en ejecución)
  5. Verificar la respuesta final

Respuestas de transmisión

La mejor manera de probar respuestas de transmisión, como eventos enviados por el servidor, es WebTestClient, que se puede utilizar como cliente de prueba para conectarse. un instancia MockMvc para ejecutar pruebas en controladores Spring MVC sin un servidor en ejecución. Por ejemplo:

Java

WebTestClient client = MockMvcWebTestClient.bindToController(new SseController()).build();
FluxExchangeResult<Person> exchangeResult = client.get()
        .uri("/persons")
        .exchange()
        .expectStatus().isOk()
        .expectHeader().contentType("text/event-stream")
        .returnResult(Person.class);
// Utilice StepVerifier de Project Reactor para probar la respuesta de transmisión
StepVerifier.create(exchangeResult.getResponseBody())
        .expectNext(new Person("N0"), new Person("N1"), new Person("N2"))
        .expectNextCount(4)
        .consumeNextWith(person -> assertThat(person.getName()).endsWith("7"))
        .thenCancel()
        .verify();

WebTestClient también puede conectarse a un servidor en vivo y ejecutar pruebas de integración completas de un extremo a otro. Esto también es compatible con Spring Boot, donde puede Probar un servidor en ejecución.

Registro de filtros

Al configurar una instancia MockMvc puede registrar una o más instancias de servlets Filter, como se muestra en el siguiente ejemplo:

Java
mockMvc = standaloneSetup(new PersonController()).addFilters(new CharacterEncodingFilter()).build();
Kotlin
// No es posible en Kotlin hasta que se solucione

Los filtros registrados se llaman a través de MockFilterChain desde spring-test, y el último filtro se delega a DispatcherServlet.

MockMvc frente a pruebas de extremo a extremo

MockMvc se basa en implementaciones simuladas de API de servlet del módulo spring-test y está independiente del contenedor en ejecución. Por lo tanto, existen algunas diferencias en comparación con las pruebas de integración completas de un extremo a otro con un cliente real y un servidor real.

La forma más sencilla de entender esto es comenzar con un MockHttpServletRequest vacío solicitud. Todo lo que le agregues se convierte en una solicitud. Cosas que pueden sorprenderle: no existe una ruta de contexto predeterminada; sin cookie jsessionid; no hay redirecciones, errores ni envío asincrónico; y por lo tanto prácticamente no hay renderizado (visualización) JSP. En cambio, las URL "redireccionadas" y "reenviadas" se almacenan en MockHttpServletResponse, después de lo cual se pueden validar con los eventos esperados.

Esto significa que si se utiliza JSP, entonces JSP puede ser validado: la página a la que se redirigió la solicitud, pero el HTML no se representará. En otras palabras, no se llama a JSP. Sin embargo, tenga en cuenta que cualquier otra tecnología de representación que no dependa de la redirección, como Thymeleaf y Freemarker, pasa HTML al cuerpo de la respuesta como se esperaba. Lo mismo se aplica a la representación de JSON, XML y otros formatos utilizando métodos anotados con @ResponseBody.

Como alternativa, es posible que desees considerar el soporte completo de Spring Boot para aplicaciones de extremo a extremo. Finalizar las pruebas de integración con anotaciones @SpringBootTest. Consulte " Primavera Guía de referencia de arranque.

Cada enfoque tiene sus ventajas y desventajas. Las opciones proporcionadas en Spring MVC Test se encuentran en diferentes lugares de la escala, desde las pruebas unitarias clásicas hasta las pruebas de integración completa. Por supuesto, ninguna de las opciones de Spring MVC Test entra en la categoría de pruebas unitarias clásicas, pero están un poco más cerca de ella. Por ejemplo, puede aislar el nivel web inyectando servicios simulados en los controladores, en cuyo caso el nivel web solo se probará a través de DispatcherServlet, pero con la configuración de Spring real, ya que puede probar el acceso a los datos. nivel por separado de los niveles superiores. Alternativamente, puede usar una configuración independiente enfocándose en un controlador a la vez y proporcionando manualmente la configuración necesaria para que funcione.

Otra diferencia importante al usar una prueba en el marco de prueba Spring MVC es que: Conceptualmente, las pruebas son del lado del servidor, por lo que tiene la capacidad de verificar qué identificador se usó, si la excepción fue manejada por HandlerExceptionResolver, cuál era el contenido del modelo, qué errores de enlace hubo y otros detalles. Esto significa que resulta más fácil escribir eventos esperados, ya que el servidor no es una caja opaca, como es el caso cuando se prueba a través de un cliente HTTP real. En general, la ventaja de las pruebas unitarias clásicas es que: dichas pruebas son más fáciles de escribir, justificar y depurar, pero no reemplazan la necesidad de pruebas de integración completas. Al mismo tiempo, es importante no perder de vista que la respuesta es lo más importante a comprobar. En resumen, hay espacio para múltiples estilos y estrategias de prueba, incluso dentro del mismo proyecto.

Ejemplos adicionales

Las pruebas propias del marco incluyen muchos casos de prueba llamado muestra cómo usar MockMvc solo o mediante WebTestClientConsulte estos ejemplos para obtener más ideas.