Saltar al contenido

Problema al probar el segmento Spring MVC en SpringBoot 1.4

Te recomendamos que revises esta resolución en un entorno controlado antes de pasarlo a producción, un saludo.

Solución:

Quien esté interesado en cargar la aplicación completa debería intentar usar @SpringBootTest combinado con @AutoConfigureMockMvc en lugar del @WebMvcTest.

He estado luchando con el problema durante bastante tiempo, pero finalmente obtuve la imagen completa.
Los numerosos tutoriales en Internet, así como la documentación oficial de Spring que encontré hasta ahora , indica que puedes probar tus controladores usando @WebMvcTest; eso es completamente correcto, aunque todavía omite la mitad de la historia.
Como lo señala el javadoc de dicha anotación, @WebMvcTest solo está destinado a probar sus controladores y no cargará todos los beans de su aplicación en absoluto, y esto es por diseño.
Incluso es incompatible con anotaciones explícitas de escaneo de beans como @Componentscan.

Sugiero a cualquier persona interesada en el asunto que lea el javadoc completo de la anotación (que tiene solo 30 líneas y está repleto de información útil condensada), pero extraeré un par de gemas relevantes para mi situación.

del tipo de anotación WebMvcTest

El uso de esta anotación deshabilitará la configuración automática completa y, en su lugar, aplicará solo la configuración relevante para las pruebas MVC (es decir, @Controller, @ControllerAdvice, @JsonComponent Filtrar, WebMvcConfigurer y HandlerMethodArgumentResolver frijoles pero no @Component, @Service o @Repository frijoles). […]
Si está buscando cargar la configuración completa de su aplicación y usar MockMVC, debe considerar @SpringBootTest combinado con @AutoConfigureMockMvc en lugar de esta anotación.

Y en realidad, solo @SpringBootTest + @AutoConfigureMockMvc solucionó mi problema, todos los demás enfoques que hacían uso de @WebMvcTest no pudo cargar algunos de los beans necesarios.

EDITAR

Retiro mi comentario que hice sobre la documentación de Spring, porque no sabía que un rodaja estaba implícito cuando uno usa un @WebMvcTest; en realidad, la documentación del segmento MVC deja en claro que no toda la aplicación está cargada, lo cual es por la naturaleza misma de un segmento.

Rebanada de prueba personalizada con Spring Boot 1.4

La segmentación de la prueba consiste en segmentar el ApplicationContext que se crea para su prueba. Típicamente, si desea probar un controlador usando MockMvc, seguramente no querrá molestarse con la capa de datos. En su lugar, probablemente desee burlarse del servicio que usa su controlador y validar que toda la interacción relacionada con la web funciona como se espera.

Tu estas usando @WebMvcTest al mismo tiempo que configura manualmente un MockMvc ejemplo. Eso no tiene sentido como uno de los propósitos principales de @WebMvcTest es configurar automáticamente un MockMvc instancia para ti. Además, en su configuración manual está utilizando standaloneSetup lo que significa que debe configurar completamente el controlador que se está probando, incluida la inyección de cualquier dependencia en él. No estás haciendo eso que causa la NullPointerException.

Si quieres usar @WebMvcTest, y te recomiendo que lo hagas, puedes eliminar tu setUp método completamente y tener un autoconfigurado MockMvc instancia inyectada en lugar de usar una @Autowired campo.

Entonces, para controlar el ProductService eso es usado por ProductController, puedes usar el nuevo @MockBean anotación para crear un simulacro ProductService que luego se inyectará en ProductController.

Estos cambios dejan su clase de prueba con este aspecto:

package guru.springframework.controllers;

import guru.springframework.services.ProductService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@WebMvcTest(ProductController.class)
public class ProductControllerTest 

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ProductService productService;

    @Test
    public void testList() throws Exception 
      mockMvc.perform(MockMvcRequestBuilders.get("/products"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                 .andExpect(MockMvcResultMatchers.view().name("products"))
                 .andExpect(MockMvcResultMatchers.model().attributeExists("products"))
               .andExpect(MockMvcResultMatchers.model().attribute("products",
                        Matchers.is(Matchers.empty())));

    

Reseñas y puntuaciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *