简体   繁体   English

如何对Spring MVC带注释的控制器进行单元测试?

[英]How to unit test a Spring MVC annotated controller?

I am following a Spring 2.5 tutorial and trying, at the same time, updating the code/setup to Spring 3.0. 我正在关注Spring 2.5教程并尝试将代码/设置更新到Spring 3.0。

In Spring 2.5 I had the HelloController (for reference): 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");
    }
}

And a JUnit test for the HelloController (for reference): 以及HelloController的JUnit测试(供参考):

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

But now I updated the controller to Spring 3.0 , and it now uses annotations (I also added a message ): 但现在我将控制器更新到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");
    }
}

Knowing that I am using JUnit 4.9, can some one explain me how to unit test this last controller? 知道我正在使用JUnit 4.9,有人可以解释一下如何对最后一个控制器进行单元测试吗?

One advantage of annotation-based Spring MVC is that they can be tested in a straightforward manner, like so: 基于注释的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());
       ...
   }
}

Is there any problem with this approach? 这种方法有什么问题吗?

For more advanced integration testing, there is a reference in Spring documentation to the org.springframework.mock.web . 对于更高级的集成测试, Spring文档中引用org.springframework.mock.web

With mvc:annotation-driven you have to have 2 steps: first you resolve the request to handler using HandlerMapping, then you can execute the method using that handler via HandlerAdapter. 使用mvc:annotation-driven,您必须有两个步骤:首先使用HandlerMapping将请求解析为处理程序,然后您可以通过HandlerAdapter使用该处理程序执行该方法。 Something like: 就像是:

@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
    }
}

This works with Spring 3.1, but I guess some variant of this must exist for every version. 这适用于Spring 3.1,但我想每个版本都必须存在一些变体。 Looking at the Spring 3.0 code, I'd say DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter should do the trick. 看看Spring 3.0代码,我会说DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter可以解决这个问题。

You can also look into other web testing frameworks that are independent of Spring like HtmlUnit , or Selenium . 您还可以查看其他独立于Spring的Web测试框架,如HtmlUnitSelenium You won't find any more robust strategy with JUnit alone other than what Sasha has described, except you should definitely assert the model. 除了Sasha描述的内容之外,你不会仅仅使用JUnit找到更强大的策略,除非你应该断言模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM