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);
}
Just create an instance of the filter, use the mock classes and check the result. You are making all your tests for this filter overly complex.
JUnit test suites help to grouping and executing tests in bulk. Executing tests separately for all test classes is not desired in most cases. Test suites help in achieving this grouping. In JUnit, test suites can be created and executed with these annotations.
ServletRequest
, ServletResponse
and FilterChain
are all interfaces, so you can easily create test stubs for them, either by hand or using a mocking framework.
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.
Inject a mock ModeService.
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());
}
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.
... 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).
You could use a mocking framework in order to mock the above HttpServletRequest
, HttpServletResponse
and FilterChain
objects and their behavior. Depending on the framework, you have certain functionality in order to verify if during the execution of the code correct actions on the mocked objects where taken.
For example when using the Mockito mock framework, the provided doFilter()
method could be JUnit tested using below test case:
@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");
}
If you are using Spring then it has own mocks:
For example, you can add headers and set test Uri.
So your test can be smth like this:
@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());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With