Mockito为了验证任何匹配者

时间:2012-12-14 14:08:21

标签: java unit-testing junit mockito

我在测试servlet过滤器时遇到了一些问题。此servlet过滤器的目的是在执行filterChain后填充响应中的一些http标头。所以我想测试的是我的mockHttpServletResponse上的setHeader调用直到调用mockFilterChain.doFilter之后才会发生。

我正在使用mockito:mockito-core:1.8.5

所以,这是一个示例代码段

@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));    
}

该测试将失败,以验证setHeader传递任何字符串参数。如果我更改setHeader验证调用以接受代码中使用的特定参数,则测试将成功通过。在验证这样的订单时,你能否使用通配符匹配器?

HeaderInjectionFilter dumbed down看起来像这样

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");
    }
}

1 个答案:

答案 0 :(得分:5)

此测试未使用任何(String.class)失败,因为在提供的Filter实现中,对response.setHeader进行了两次后续调用。 inOrder.verify验证交互是按顺序发生的。从技术上讲,测试可以改为

@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));    
}

或者,测试应该明确地测试设置的特定标题,这是我要去的路径,因为对于阅读测试的人来说它不那么模糊。