我如何单元测试使用JUnit一个Servlet过滤器?(How do I unit test a S

2019-06-26 05:47发布

实现doFilter() 如何正确地覆盖过滤器使用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);
}

Answer 1:

ServletRequestServletResponseFilterChain的所有接口,让您可以轻松地为他们创造测试桩,手工或用讽刺的框架。

让模拟对象可配置的,这样就可以准备罐头回应getRequestURI()等,你可以查询ServletResponse的断言的sendRedirect已被调用。

注入模拟ModeService。

调用的doFilter通过模拟的ServletRequest,ServletResponse的和FilterChain作为它的参数。

@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方法来涵盖所有可能的执行路径。

......你可能会使用像JMock的或一个的Mockito嘲讽的框架来创建嘲弄,而不是假想MockModeService等我在这里使用。

这是一个单元测试的方法,而不是一个集成测试。 你只行使被测单元(和测试代码)。



Answer 2:

你可以使用一个嘲讽的框架,以嘲笑以上HttpServletRequestHttpServletResponseFilterChain对象及其行为。 根据不同的框架,你才能在哪里拍摄的嘲笑对象的代码正确动作的执行过程中,以验证是否具有某些功能。

对于使用模拟的Mockito框架时例如,所提供doFilter()方法可以是使用的JUnit下面测试用例测试:

@Test
public void testDoFilter() throws IOException, ServletException {
    // create the objects to be mocked
    HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
    HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
    FilterChain filterChain = mock(FilterChain.class);
    // mock the getRequestURI() response
    when(httpServletRequest.getRequestURI()).thenReturn("/otherurl.jsp");

    MaintenanceFilter maintenanceFilter = new MaintenanceFilter();
    maintenanceFilter.doFilter(httpServletRequest, httpServletResponse,
            filterChain);

    // verify if a sendRedirect() was performed with the expected value
    verify(httpServletResponse).sendRedirect("/maintenance.jsp");
}


Answer 3:

如果您在使用Spring那么它有自己的嘲笑:

  • org.springframework.mock.web.MockFilterChain
  • org.springframework.mock.web.MockHttpServletRequest
  • org.springframework.mock.web.MockHttpServletResponse

例如,您可以添加标题,并设置测试URI。

所以,你的测试可以是水木清华这样的:

@RunWith(MockitoJUnitRunner.class)
public class TokenAuthenticationFilterTest {

    private static final String token = "260bce87-6be9-4897-add7-b3b675952538";
    private static final String testUri = "/testUri";

    @Mock
    private SecurityService securityService;

    @InjectMocks
    private TokenAuthenticationFilter tokenAuthenticationFilter = new TokenAuthenticationFilter();

    @Test
    public void testDoFilterInternalPositiveScenarioWhenTokenIsInHeader() throws ServletException, IOException {
        MockHttpServletRequest request = new MockHttpServletRequest();
        request.addHeader(TOKEN, token);
        request.setRequestURI(testUri);
        MockHttpServletResponse response = new MockHttpServletResponse();
        MockFilterChain filterChain = new MockFilterChain();
        when(securityService.doesExistToken(token)).thenReturn(true);
        tokenAuthenticationFilter.doFilterInternal(request, response, filterChain);
        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
    }
}


文章来源: How do I unit test a Servlet Filter with jUnit?
标签: java junit