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

2022-09-02 05:38:10

我正在学习Spring 2.5教程,同时尝试将代码/设置更新到Spring 3.0。

春季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");
    }
}

以及 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());
    }
}

但是现在我将控制器更新到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");
    }
}

知道我正在使用JUnit 4.9,有人可以解释一下如何对最后一个控制器进行单元测试吗?


答案 1

基于注释的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());
       ...
   }
}

这种方法有什么问题吗?

对于更高级的集成测试,Spring文档中引用了org.springframework.mock.web


答案 2

使用 mvc:annotation 驱动的,你必须有 2 个步骤:首先使用 HandlerMapping 解析对处理程序的请求,然后你可以通过 HandlerAdapter 使用该处理程序执行该方法。像这样:

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

这适用于Spring 3.1,但我想每个版本都必须存在一些变体。看看Spring 3.0代码,我会说DefaultAnnotationHandlerMapping和NotementMethodHandlerAdapter应该可以做到这一点。


推荐