如何使用jUnit对Servlet过滤器进行单元测试?

如何使用jUnit对Servlet过滤器进行单元测试?

问题描述:

已实施 doFilter()。如何用jUnit正确覆盖Filter?

Implemented doFilter(). How to properly cover Filter with jUnit ?

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws java.io.IOException, javax.servlet.ServletException
{
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String currentURL = request.getRequestURI();

    if (!currentURL.equals("/maintenance.jsp") && modeService.getOnline())
    {
        response.sendRedirect("/maintenance.jsp");
    }
    filterChain.doFilter(servletRequest, servletResponse);
}


ServletRequest ServletResponse FilterChain 都是接口,因此您可以轻松创建测试存根它们可以手动或使用模拟框架。

ServletRequest, ServletResponse and FilterChain are all interfaces, so you can easily create test stubs for them, either by hand or using a mocking framework.

使模拟对象可配置,以便您可以准备对 getRequestURI()以便您可以查询ServletResponse以断言已调用sendRedirect。

Make the mock objects configurable so that you can prepare a canned response to getRequestURI() and so that you can query the ServletResponse to assert that sendRedirect has been invoked.

注入模拟ModeService。

Inject a mock ModeService.

调用doFilter,将模拟ServletRequest,ServletResponse和FilterChain作为参数传递。

Invoke doFilter passing the mock ServletRequest, ServletResponse and FilterChain as its parameters.

@Test
public void testSomethingAboutDoFilter() {
    MyFilter filterUnderTest = new MyFilter();
    filterUnderTest.setModeService(new MockModeService(ModeService.ONLINE));
    MockFilterChain mockChain = new MockFilterChain();
    MockServletRequest req = new MockServletRequest("/maintenance.jsp");
    MockServletResponse rsp = new MockServletResponse();

    filterUnderTest.doFilter(req, rsp, mockChain);

    assertEquals("/maintenance.jsp",rsp.getLastRedirect());
}

实际上,您需要将设置移至@Before setUp()方法,并编写更多@Test方法来覆盖每个可能的执行路径。

In practice you'll want to move the setup into an @Before setUp() method, and write more @Test methods to cover every possible execution path.

...你可能会使用像JMock或Mockito这样的模拟框架来创建模拟,而不是假设的 MockModeService 等我在这里使用过。

... and you'd probably use a mocking framework like JMock or Mockito to create mocks, rather than the hypothetical MockModeService etc. I've used here.

这是一个单元测试方法,而不是集成测试。您只是在运行被测单元(以及测试代码)。

This is a unit testing approach, as opposed to an integration test. You are only exercising the unit under test (and the test code).