java - Mockito 为了验证任何匹配器

标签 java unit-testing junit mockito

我在测试 servlet 过滤器时遇到了一些问题。此 servlet 过滤器的目的是在执行 filterChain 后在响应中填充一些 http header 。因此,我要测试的是,在调用 mockFilterChain.doFilter 之前,不会发生对我的 mockHttpServletResponse 的 setHeader 调用。

我正在使用 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 看起来像这样

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

最佳答案

此测试使用 any(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));    
}

或者,测试应该明确地测试设置了特定的 header ,这是我要走的路,因为它对于阅读测试的人来说不那么晦涩。

关于java - Mockito 为了验证任何匹配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13880254/

相关文章:

java - Collections.sort 具有多个字段

JavaFX 通过数据库值更改行颜色

javascript - 模拟命名导入和构造函数 ES6 和 Ava

c# - Pex(及其输出)是否适合企业环境?

javascript - Cypress 测试框架

java - Gradle 找不到 JUnit 测试

java - 在java中绘制多个椭圆

java - 拦截器必须是bean吗?

java - 需要像 JUnit4 一样的 JUnit 3 假设或 Java 1.4 可用的等效技术

Spring、spring Batch、hibernate 和 JUnit 以及多个集成测试的初始化