使用Spring 3.1,您如何测试控制器的URL?

时间:2012-10-08 04:56:10

标签: java spring unit-testing spring-mvc controller

在spring(3.0)的早期版本中,可以使用ApplicationContext中的RequestMappingHandlerAdapter和HandlerMapping对象通过正确的URL测试控制器。但是,在Spring 3.1中,事情发生了变化,我以前使用的代码不再起作用。

如何在Spring 3.1中测试Spring控制器URL?例如,我想编写如下代码:

ModelAndView modelAndView = handle("GET", "/businesses");

除了控制器的动作逻辑之外,我还在测试我的映射。

特别是,我最感兴趣的是确保我可以传递会话属性并将它们正确地传递给我的控制器操作@Valid注释。

有没有办法用Spring 3.1实现这个目标?

这是我正在使用的代码:

protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    final HandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);

    final HandlerExecutionChain handler = handlerMapping.getHandler(request);
    assertNotNull("No handler found for request, check you request mapping", handler);

    final Object controller = handler.getHandler();

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

    return handlerAdapter.handle(request, response, controller);
}

protected ModelAndView handle(String method, String path, String queryString) throws Exception {
    request.setMethod(method);
    request.setRequestURI(path);

    if(queryString != null) {
        String[] parameters = queryString.split("&");
        for(String parameter : parameters) {
            String[] pair = parameter.split("=");
            if(pair.length == 2) {
                request.setParameter(pair[0], pair[1]);
            } else {
                request.setParameter(pair[0], "");
            }
        }
    }

    return handle(request, response);
}

protected ModelAndView handle(String method, String path, String attribute, Object object) throws Exception {
    MockHttpSession session = new MockHttpSession();
    session.setAttribute(attribute, object);
    request.setSession(session);

    return handle(method, path, null);
}

protected ModelAndView handle(String method, String path) throws Exception {
    return handle(method, path, null);
}

protected void assertContentType(ModelAndView modelAndView, String contentType) {
    assertEquals(contentType, modelAndView.getView().getContentType());
}

3 个答案:

答案 0 :(得分:1)

这是我在Spring 3.1中使用的测试用例之一。希望它能满足你的要求。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml" })
public class ControllerTest {
    @Autowired
    private RequestMappingHandlerAdapter handleAdapter;

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;
    @Test
    public void playerControllerTest() throws Exception{

        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();
        request.setRequestURI("/players.show");
        request.setMethod("GET");

        Object handler = handlerMapping.getHandler(request).getHandler();
        ModelAndView mav = handleAdapter.handle(request, response,handler);

        ModelAndViewAssert.assertViewName(mav,"players");

    }

}

答案 1 :(得分:1)

让我改为推荐目前在1.0.0M1中的spring-test-mvc,但计划与更新的Spring MVC版本一起打包。它应该能够很容易地处理您正在寻找的案例,您的测试最终会看起来像这样:

xmlConfigSetup("classpath:/META-INF/spring/web/webmvc-config.xml")
            .configureWebAppRootDir("src/main/webapp", false).build()
            .perform(get("/businesses").param("name", "param1"))
            .andExpect(status().isOk())
            .andExpect(view().name("viewname"));

你的测试确实看起来适合3.1,所以如果你仍然想继续你的方法,你可以准确指出什么是无效的 - 听起来像正常的请求正在通过,但会话属性似乎没有绑定?

答案 2 :(得分:0)

Here是一个非常好的演示文稿,讨论测试Spring 3.1类和控制器,以下是一个例子:

@Test
public void testSave() {

    Account account = new Account();
    BindingResult result = 
        new BeanPropertyBindingResult(account, "account");

    AccountManager mgr = createMock(AccountManager.class);
    mgr.saveOrUpdate(account);
    replay(mgr);

    AccountController contrlr = new AccountController(mgr);

    String view = contrlr.save(account, result);

    assertEquals("redirect:accounts", view);
    verify(mgr);
}

希望有所帮助!