簡體   English   中英

如何使用jUnit對Servlet過濾器進行單元測試?

[英]How do I unit test a Servlet Filter with jUnit?

實現了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);
}

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等。我在這里使用過。

這是一種單元測試方法,而不是集成測試。 您只是在運行被測單元(和測試代碼)。

您可以使用模擬框架來模擬上面的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");
}

如果您使用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());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM