Как выполнить юнит-тестирование аннотированного контроллера Spring MVC - PullRequest
20 голосов
/ 25 апреля 2011

Я следую учебнику Spring 2.5 и одновременно пытаюсь обновить код / ​​настройки до Spring 3.0.

В Spring 2.5 У меня был HelloController (для справки):

public class HelloController implements Controller {
    protected final Log logger = LogFactory.getLog(getClass());
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.info("Returning hello view");
        return new ModelAndView("hello.jsp");
    }
}

И тест JUnit для HelloController (для справки):

public class HelloControllerTests extends TestCase {
    public void testHandleRequestView() throws Exception{
        HelloController controller = new HelloController();
        ModelAndView modelAndView = controller.handleRequest(null, null);
        assertEquals("hello", modelAndView.getViewName());
    }
}

Но теперь я обновил контроллер до Spring 3.0 , и теперь он использует аннотации (я также добавил сообщение ):

@Controller
public class HelloController {
    protected final Log logger = LogFactory.getLog(getClass());
    @RequestMapping("/hello")
    public ModelAndView handleRequest() {
        logger.info("Returning hello view");
        return new ModelAndView("hello", "message", "THIS IS A MESSAGE");
    }
}

Зная, что я использую JUnit 4.9, может кто-нибудь объяснить мнекак провести модульное тестирование последнего контроллера?

Ответы [ 3 ]

25 голосов
/ 25 апреля 2011

Одним из преимуществ Spring MVC на основе аннотаций является то, что их можно тестировать простым способом, например так:

import org.junit.Test;
import org.junit.Assert;
import org.springframework.web.servlet.ModelAndView;

public class HelloControllerTest {
   @Test
   public void testHelloController() {
       HelloController c= new HelloController();
       ModelAndView mav= c.handleRequest();
       Assert.assertEquals("hello", mav.getViewName());
       ...
   }
}

Есть ли проблемы с этим подходом?

Для получения дополнительной информацииВ расширенном интеграционном тестировании в документации Spring есть ссылка *1007* на org.springframework.mock.web .

21 голосов
/ 27 октября 2011

В mvc: annotation-based вам нужно выполнить 2 шага: сначала вы разрешаете запрос к обработчику с помощью HandlerMapping, затем вы можете выполнить метод с помощью этого обработчика через HandlerAdapter. Что-то вроде:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("yourContext.xml")
public class ControllerTest {

    @Autowired
    private RequestMappingHandlerAdapter handlerAdapter;

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;

    @Test
    public void testController() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest();
        // request init here

        MockHttpServletResponse response = new MockHttpServletResponse();
        Object handler = handlerMapping.getHandler(request).getHandler();
        ModelAndView modelAndView = handlerAdapter.handle(request, response, handler);

        // modelAndView and/or response asserts here
    }
}

Это работает с Spring 3.1, но я предполагаю, что какой-то вариант этого должен существовать для каждой версии. Глядя на код Spring 3.0, я бы сказал, что DefaultAnnotationHandlerMapping и AnnotationMethodHandlerAdapter должны помочь.

1 голос
/ 25 апреля 2011

Вы также можете посмотреть другие платформы веб-тестирования, которые не зависят от Spring, такие как HtmlUnit или Selenium .Только с JUnit вы не найдете более надежной стратегии, кроме той, что описал Саша, за исключением того, что вам обязательно следует утверждать модель.

...