Soy nuevo en Spring Boot y estoy tratando de entender cómo funcionan las pruebas en SpringBoot. Estoy un poco confundido acerca de cuál es la diferencia entre los siguientes dos fragmentos de código:
Fragmento de código 1:
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerApplicationTest {
@Autowired
private MockMvc mvc;
@Test
public void getHello() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Greetings from Spring Boot!")));
}
}
Esta prueba usa la @WebMvcTest
anotación que creo que es para pruebas de segmentos de características y solo prueba la capa MVC de una aplicación web.
Fragmento de código 2:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void getHello() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Greetings from Spring Boot!")));
}
}
Esta prueba usa la @SpringBootTest
anotación y un MockMvc
. Entonces, ¿en qué se diferencia esto del fragmento de código 1? ¿Qué hace esto de manera diferente?
Editar: Agregar fragmento de código 3 (Encontré esto como un ejemplo de prueba de integración en la documentación de Spring)
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {
@LocalServerPort private int port;
private URL base;
@Autowired private TestRestTemplate template;
@Before public void setUp() throws Exception {
this.base = new URL("http://localhost:" + port + "/");
}
@Test public void getHello() throws Exception {
ResponseEntity < String > response = template.getForEntity(base.toString(), String.class);
assertThat(response.getBody(), equalTo("Greetings from Spring Boot!"));
}
}
fuente
SpringBootTest
está cargando su aplicación completa (hasta cierto punto, de forma predeterminada no iniciará el contenedor incrustado si hay uno disponible, para esowebEnvironment
está). No diría que@SpringBootTest
es una prueba unitaria del controlador, sino más una prueba de integración, en realidad.WebMvcTest
es realmente una prueba unitaria de su controlador en el sentido de que si tiene dependencia, tendrá que proporcionarlos usted mismo (ya sea una configuración o una simulación de algún tipo).SpringBootTest
yWebMvcTest
crea son muy diferentes. El primero carga TODA su aplicación y habilita TODAS las configuraciones automáticas, mientras que el segundo solo habilita Spring Mvc y no escanea nada más queHelloController
. Después de todo, todo depende de lo que quieras decir con prueba unitaria. Pero esa es la diferencia.@SpringBootTest anotación le dice a Spring Boot que busque una clase de configuración principal (una con @SpringBootApplication, por ejemplo), y úsela para iniciar un contexto de aplicación Spring. SpringBootTest carga la aplicación completa e inyecta todos los beans, lo que puede ser lento.
@WebMvcTest : para probar la capa del controlador y debe proporcionar las dependencias restantes requeridas mediante Mock Objects.
Algunas anotaciones más a continuación para su referencia.
Prueba de segmentos de la aplicación A veces, le gustaría probar un simple "segmento" de la aplicación en lugar de configurar automáticamente toda la aplicación. Spring Boot 1.4 presenta 4 nuevas anotaciones de prueba:
Consulte para obtener más información: https://spring.io/guides/gs/testing-web/
fuente
Las pruebas MVC están destinadas a cubrir solo la parte del controlador de su aplicación. Las solicitudes y respuestas HTTP se simulan para que no se creen conexiones reales. Por otro lado, cuando lo utiliza
@SpringBootTest
, toda la configuración para el contexto de la aplicación web se carga y las conexiones pasan por el servidor web real. En ese caso, no usa elMockMvc
bean sino un estándarRestTemplate
(o la nueva alternativaTestRestTemplate
).Entonces, ¿cuándo deberíamos elegir uno u otro?
@WebMvcTest
está destinado a probar unitariamente el controlador desde el lado del servidor.@SpringBootTest
, por otro lado, debe usarse para pruebas de integración, cuando desee interactuar con la aplicación desde el lado del cliente.Eso no significa que no puedas usar simulacros con
@SpringBootTest
; si está escribiendo una prueba de integración, aún podría ser necesario. En cualquier caso, es mejor no usarlo solo para una simple prueba unitaria del controlador.fuente - Aprendizaje de microservicios con Spring Boot
fuente
@SpringBootTest
, un servidor web real no se inicia a menos que también tengawebEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
(o aDEFINED_PORT
) y las conexiones no pasen por el servidor web real. El valor predeterminado@SpringBootTest
esWebEnvironment.MOCK
.