代码之家  ›  专栏  ›  技术社区  ›  hal9000

相关Id的单元测试过滤器

  •  0
  • hal9000  · 技术社区  · 6 年前

    我做了一个过滤器来截取并记录调用服务的相关ID。

    以下是筛选器:

    public class CorrelationIdServletFilter implements Filter {
    
    private static final Logger LOGGER =
      LoggerFactory.getLogger(CorrelationIdServletFilter.class);
    
     private static final String CORRELATION_ID_HEADER_NAME = "Correlation-ID";
    
     private static final String CORRELATION_ID_MDC_KEY = " ";
    
     private static final InheritableThreadLocal<String> correlationId =
      new InheritableThreadLocal<>();
    
      public static String getCorrelationId() {
    return correlationId.get();
     }
    
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {}
    
     @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    
    try {
      HttpServletRequest req = (HttpServletRequest) request;
    
      HttpServletResponse res = (HttpServletResponse) response;
    
      String correlationIdHeaderValue = req.getHeader(CORRELATION_ID_HEADER_NAME);
    
      LOGGER.debug
          (
          "HTTP Header("
              + CORRELATION_ID_HEADER_NAME
              + ") = ["
              + correlationIdHeaderValue
              + "] will generate a new correlationId if incoming is NULL");
    
      String correlationIdRaw;
    
      if (!StringUtils.isEmpty(correlationIdHeaderValue)) {
        correlationIdRaw = correlationIdHeaderValue;
      } else {
        correlationIdRaw = UUID.randomUUID().toString();
      }
    
      LOGGER.debug("Request: (" + req.getRequestURI() + ") is marked as :" + correlationIdRaw);
    
      correlationId.set(correlationIdRaw);
    
      MDC.put(CORRELATION_ID_MDC_KEY, getCorrelationId());
    
      res.addHeader(CORRELATION_ID_HEADER_NAME, correlationIdRaw);
    
      LOGGER.debug(
          "Response holds correlationId : ("
              + res.getHeader("Correlation-ID")
              + ") in its header ");
    
      chain.doFilter(req, res);
    
    } finally {
      correlationId.remove();
      MDC.remove(CORRELATION_ID_MDC_KEY);
    }
    }
    
      @Override
      public void destroy() {}
    }
    

    我需要编写单元测试来涵盖两种情况:

    1. 如果发送的请求没有相关Id,请检查服务器端是否生成了Id。

    有人能告诉我怎么做吗?

    我试着用mock,但我不知道响应在标题中没有任何内容。

    @Test
      public void testResponse_for_RequestWithoutCcid() throws IOException, ServletException {
    
    HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
    HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
    FilterChain filterChain = mock(FilterChain.class);
    CorrelationIdServletFilter CorrelationIdServletFilter = mock(
        CorrelationIdServletFilter.class);
    CorrelationIdServletFilter.init(mock(FilterConfig.class));
    
    CorrelationIdServletFilter.doFilter(httpServletRequest, httpServletResponse,
        filterChain);
    
    
    System.out.println(httpServletResponse.getHeaderNames());
    
    CorrelationIdServletFilter.destroy();
    
    verify(CorrelationIdServletFilter, times(1))
        .doFilter(httpServletRequest, httpServletResponse, filterChain);
    
    }
    

    有什么办法我能做到吗?任何帮助都将不胜感激。有没有办法不用嘲弄?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Apoorv Agarwal    6 年前

    您编写的测试的一些主要问题:

    1. init 以及 destroy doFilter 方法。
    2. 当我们创建任何模拟对象时,我们使用期望来定义我们期望对模拟对象进行的调用,并让它们在需要时返回一些存根值。

    现在,我已经尝试编写正确的测试来断言您要测试的两个案例:

    @Test
    public void testResponse_for_RequestWithoutCcid() throws IOException, ServletException {
    
    HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
    HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
    FilterChain filterChain = mock(FilterChain.class);
    CorrelationIdServletFilter correlationIdServletFilter = new CorrelationIdServletFilter();
    
    expect(httpServletRequest.getHeader(CORRELATION_ID_HEADER_NAME)).andReturn(""); // Empty correlation id in the request
    
    Capture capturedCorrelationIdRaw = newCapture();
    
    httpServletResponse.addHeader(CORRELATION_ID_HEADER_NAME, capture(capturedCorrelationIdRaw));
    expectLastCall(); // used for void methods in EasyMock framework
    
    filterChain.doFilter(httpServletRequest, httpServletResponse);
    expectLastCall();
    
    CorrelationIdServletFilter.doFilter(httpServletRequest, httpServletResponse,
        filterChain);
    
    
    assertNotEmpty(capturedCorrelationIdRaw.getValue());
    
    
    verify(httpServletRequest, times(1))
        .getHeader(CORRELATION_ID_HEADER_NAME);
    verify(httpServletResponse, times(1))
        .addHeader(CORRELATION_ID_HEADER_NAME, anyString);
    
    }
    

    这个测试需要根据实际使用的测试框架进行更新,但是我已经尽了最大努力让您了解测试应该是什么样子的。