简体   繁体   English

Mockito以便与任何匹配者进行验证

[英]Mockito in order verify with any matchers

I'm having some issues testing a servlet filter. 我在测试servlet过滤器时遇到一些问题。 The purpose of this servlet filter is to populate some http headers on response after the filterChain has been executed. 此Servlet筛选器的目的是在执行filterChain之后在响应时填充一些http标头。 So what I am trying to test is that setHeader calls on my mockHttpServletResponse don't happen until after mockFilterChain.doFilter is called. 因此,我要测试的是,直到调用嘲笑FilterChain.doFilter之后,才会对我的mockHttpServletResponse进行setHeader调用。

I am using mockito:mockito-core:1.8.5 我正在使用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. 该测试将无法验证setHeader是否通过任何字符串参数。 If I change that setHeader verification call to accept specific arguments that are used in the code the test will pass successfully. 如果我将setHeader验证调用更改为接受代码中使用的特定参数,则测试将成功通过。 Can you not use wildcard matchers when you are verifying order like this? 验证这样的订单时,可以不使用通配符匹配器吗?

HeaderInjectionFilter dumbed down looks like this HeaderInjectionFilter愚蠢的看起来像这样

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

This test was failing using any(String.class) because in the Filter implementation provided, two subsequent calls to response.setHeader. 使用any(String.class)导致该测试失败,因为在提供的Filter实现中,随后有两个对response.setHeader的调用。 inOrder.verify verifies that the interaction happens once in order. inOrder.verify验证交互是否按顺序进行了一次。 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. 或者,测试应该显式地测试设置的特定标头,这是我要走的路径,因为对于阅读该测试的人来说,它不太明显。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM