Reputation: 4208
I'm having some issues testing a servlet filter. The purpose of this servlet filter is to populate some http headers on response after the filterChain has been executed. So what I am trying to test is that setHeader calls on my mockHttpServletResponse don't happen until after mockFilterChain.doFilter is called.
I am using mockito:mockito-core:1.8.5
So, here is a sample code snippet
@Test
public void filterHeaderInjectionHappensLast() throws Exception {
javax.servlet.Filter myFilter = new HeaderInjectionFilter();
mockRequest = mock(javax.servlet.http.HttpServletRequest.class);
mockResponse = mock(javax.servlet.http.HttpServletResponse.class);
mockFilterChain = mock(javax.servlet.FilterChain.class);
myFilter.doFilter(mockRequest, mockResponse, mockFilterChain);
InOrder inOrder = inOrder(mockFilterChain, mockResponse);
inOrder.verify(mockFilterChain).doFilter(mockRequest,mockResponse);
inOrder.verify(mockResponse).setHeader(any(String.class),any(String.class));
}
That test will fail do to the verify of setHeader passing any string arguments. If I change that setHeader verification call to accept specific arguments that are used in the code the test will pass successfully. Can you not use wildcard matchers when you are verifying order like this?
HeaderInjectionFilter dumbed down looks like this
public class HeaderInjectionFilter implements Filter {
@Override
public void destroy() {}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(request, response); //Always doFilter before we add header to response
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader(CACHE_CONTROL, "no-cache");
httpServletResponse.setHeader(PRAGMA, "no-cache");
}
}
Upvotes: 1
Views: 7790
Reputation: 4208
This test was failing using any(String.class) because in the Filter implementation provided, two subsequent calls to response.setHeader. inOrder.verify verifies that the interaction happens once in order. So technically the test could be altered to
@Test
public void filterHeaderInjectionHappensLast() throws Exception {
javax.servlet.Filter myFilter = new HeaderInjectionFilter();
mockRequest = mock(javax.servlet.http.HttpServletRequest.class);
mockResponse = mock(javax.servlet.http.HttpServletResponse.class);
mockFilterChain = mock(javax.servlet.FilterChain.class);
myFilter.doFilter(mockRequest, mockResponse, mockFilterChain);
InOrder inOrder = inOrder(mockFilterChain, mockResponse);
inOrder.verify(mockFilterChain).doFilter(mockRequest,mockResponse);
inOrder.verify(mockResponse, times(2)).setHeader(any(String.class),any(String.class));
}
Or, the test should explicitely test the specific header was set which is the path I would go down since it is less obscure for someone reading the test.
Upvotes: 5