测试Spring MVC注释映射

使用Spring MVC,您可以指定特定URL将由特定方法处理,并且您可以指定特定参数将映射到特定参数,如下所示:

@Controller public class ImageController { @RequestMapping("/getImage") public String getImage( @RequestParam("imageId") int imageId, Map model ) { model.put("image",ImageService.getImage(imageId)); } } 

这一切都很好,但现在我想测试带有imageId参数的http请求将正确调用此方法。 换句话说,如果我删除或更改任何注释,我想要一个会破坏的测试。 有没有办法做到这一点?

很容易测试getImage是否正常工作。 我可以创建一个ImageController并使用适当的参数调用getImage。 但是,这只是测试的一半。 测试的另一半必须是当适当的HTTP请求进入时,Spring框架是否会调用getImage()。我觉得我还需要对此部分进行测试,特别是当我的@RequestMapping注释变得更加复杂并调用时复杂的参数条件。

如果我删除第4行,@ @RequestMapping("getImage") ,你能告诉我一个测试会破坏吗?

您可以以编程方式使用AnnotationMethodHandlerAdapter及其handle方法。 这将解析给定请求的方法并执行它。 不幸的是,这有点间接。 实际上在AMHA中有一个名为ServletHandlerMethodResolver的私有类,它负责解析给定请求的方法。 我刚刚提出了关于该主题的改进请求 ,因为我真的希望看到这也是可能的。

在此期间,您可以使用例如EasyMock来创建控制器类的模拟,期望调用给定的方法并将该模拟handle

控制器:

 @Controller public class MyController { @RequestMapping("/users") public void foo(HttpServletResponse response) { // your controller code } } 

测试:

 public class RequestMappingTest { private MockHttpServletRequest request; private MockHttpServletResponse response; private MyController controller; private AnnotationMethodHandlerAdapter adapter; @Before public void setUp() { controller = EasyMock.createNiceMock(MyController.class); adapter = new AnnotationMethodHandlerAdapter(); request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); } @Test public void testname() throws Exception { request.setRequestURI("/users"); controller.foo(response); EasyMock.expectLastCall().once(); EasyMock.replay(controller); adapter.handle(request, response, controller); EasyMock.verify(controller); } } 

此致,奥利

Ollie的解决方案包括测试注释的具体示例,但是如何测试所有其他各种Spring MVC注释的更广泛的问题呢? 我的方法(可以很容易地扩展到其他注释)将是

 import static org.springframework.test.web.ModelAndViewAssert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({/* include live config here eg "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; private MyController controller; @Before public void setUp() { request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); handlerAdapter = applicationContext.getBean(HandlerAdapter.class); // I could get the controller from the context here controller = new MyController(); } @Test public void testFoo() throws Exception { request.setRequestURI("/users"); final ModelAndView mav = handlerAdapter.handle(request, response, controller); assertViewName(mav, null); assertAndReturnModelAttributeOfType(mav, "image", Image.class); } } 

我还写了一篇关于集成测试Spring MVC注释的博客文章 。