使用Spring MVC,您可以指定特定URL将由特定方法处理,并且您可以指定特定参数将映射到特定参数,如下所示:
@Controller
public class ImageController {
@RequestMapping("/getImage")
public String getImage( @RequestParam("imageId") int imageId, Map<String,Object> model ) {
model.put("image",ImageService.getImage(imageId));
}
}
这一切都很好,但现在我想测试带有imageId参数的http请求将正确调用此方法。换句话说,如果我删除或更改任何注释,我想要一个会破坏的测试。有没有办法做到这一点?
很容易测试getImage是否正常工作。我可以创建一个ImageController并使用适当的参数调用getImage。但是,这只是测试的一半。测试的另一半必须是当适当的HTTP请求进入时,Spring框架是否会调用getImage()。我觉得我还需要对此部分进行测试,特别是当我的@RequestMapping
注释变得更多时复杂并调用复杂的参数条件。
如果我删除第4行@RequestMapping("getImage")
?
答案 0 :(得分:13)
您可以通过编程方式使用AnnotationMethodHandlerAdapter及其handle
方法。这将解析给定请求的方法并执行它。不幸的是,这有点间接。实际上,AMHA中有一个名为ServletHandlerMethodResolver
的私有类,它负责解析给定请求的方法。我刚刚就该主题提交了request for improvement,因为我真的希望看到这一点。
在此期间你可以使用例如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);
}
}
此致 奥利
答案 1 :(得分:7)
Ollie的解决方案包括测试注释的具体示例,但是如何测试所有其他各种Spring MVC注释的更广泛问题呢?我的方法(可以很容易地扩展到其他注释)将是
import static org.springframework.test.web.ModelAndViewAssert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({/* include live config here
e.g. "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);
}
}
我还写了blog entry about integration testing Spring MVC annotations。