Тестирование Spring @MVC аннотации

Я столкнулся с проблемой на днях, куда @Valid аннотация была случайно удалена из класса контроллера. К сожалению, это не повредило ни одного из наших тестов. Ни один из наших модульных тестов на самом деле не осуществляет Spring AnnotationMethodHandlerAdapter трасса. Мы просто тестируем наши классы контроллера непосредственно.

Как я могу записать модульный или интеграционный тест, который правильно перестанет работать, если мои @MVC аннотации будут неправильными? Существует ли способ, которым я могу попросить, чтобы Spring нашел и осуществил соответствующий контроллер с MockHttpServlet или чем-то?

9
задан skaffman 22 February 2010 в 21:49
поделиться

2 ответа

Конечно. Нет причин, почему ваш тест не может создать свой собственный DispatcherServlet, инжектировать его с различными элементами, которые он будет иметь в контейнере (например, ServletContext), включая расположение файла определения контекста.

Spring поставляется с множеством связанных с сервлетами классов MockXYZ для этой цели, включая MockServletContext, MockHttpServletRequest и MockHttpServletResponse. Это не совсем "подражательные" объекты в обычном смысле, они больше похожи на тупые заглушки, но свою работу они выполняют.

Тестовый контекст сервлета будет содержать обычные бобы, связанные с MVC, плюс ваши бобы для тестирования. После инициализации сервлета создайте имитационные запросы и ответы и передайте их в метод service() сервлета. Если запрос отправлен правильно, вы можете проверить результаты, записанные в макет ответа.

3
ответ дан 4 December 2019 в 12:17
поделиться

Я пишу интеграционные тесты для такого рода вещей. Скажем, у вас есть боб с аннотациями валидации:

public class MyForm {
    @NotNull
    private Long myNumber;

    ...
}

и контроллер, который обрабатывает отправку

@Controller
@RequestMapping("/simple-form")
public class MyController {
    private final static String FORM_VIEW = null;

    @RequestMapping(method = RequestMethod.POST)
    public String processFormSubmission(@Valid MyForm myForm,
            BindingResult result) {
        if (result.hasErrors()) {
            return FORM_VIEW;
        }
        // process the form
        return "success-view";
    }
}

и вы хотите проверить, что аннотации @Valid и @NotNull подключены правильно:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:web/WEB-INF/application-context.xml",
    "file:web/WEB-INF/dispatcher-servlet.xml"})
public class MyControllerIntegrationTest {

    @Inject
    private ApplicationContext applicationContext;

    private MockHttpServletRequest request;
    private MockHttpServletResponse response;
    private HandlerAdapter handlerAdapter;

    @Before
    public void setUp() throws Exception {
        this.request = new MockHttpServletRequest();
        this.response = new MockHttpServletResponse();

        this.handlerAdapter = applicationContext.getBean(HandlerAdapter.class);
    }

    ModelAndView handle(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        final HandlerMapping handlerMapping = applicationContext.getBean(HandlerMapping.class);
        final HandlerExecutionChain handler = handlerMapping.getHandler(request);
        assertNotNull("No handler found for request, check you request mapping", handler);

        final Object controller = handler.getHandler();
        // if you want to override any injected attributes do it here

        final HandlerInterceptor[] interceptors =
            handlerMapping.getHandler(request).getInterceptors();
        for (HandlerInterceptor interceptor : interceptors) {
            final boolean carryOn = interceptor.preHandle(request, response, controller);
            if (!carryOn) {
                return null;
            }
        }

        final ModelAndView mav = handlerAdapter.handle(request, response, controller);
        return mav;
    }

    @Test
    public void testProcessFormSubmission() throws Exception {
        request.setMethod("POST");
        request.setRequestURI("/simple-form");
        request.setParameter("myNumber", "");

        final ModelAndView mav = handle(request, response);
        // test we're returned back to the form
        assertViewName(mav, "simple-form");
        // make assertions on the errors
        final BindingResult errors = assertAndReturnModelAttributeOfType(mav, 
                "org.springframework.validation.BindingResult.myForm", 
                BindingResult.class);
        assertEquals(1, errors.getErrorCount());
        assertEquals("", errors.getFieldValue("myNumber"));        
    }

См. мой блог о интеграционном тестировании аннотаций Spring в MVC

13
ответ дан 4 December 2019 в 12:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: