1

在 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());
}
4

3 回答 3

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");

    }

}
于 2012-10-08T08:24:30.290 回答
1

让我推荐一下spring-test-mvc,它目前在 1.0.0M1 中,但计划与更新的 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,因此如果您仍想继续使用您的方法,您能否准确指出什么不起作用 - 听起来正常请求正在通过但会话属性似乎没有绑定?

于 2012-10-10T00:20:38.607 回答
0

是一个非常好的演示文稿,它讨论了测试 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);
}

希望有帮助!

于 2012-10-08T05:10:05.773 回答