如何编写集成测试来检查 MDC 上下文中的内容?

dev*_*eak 5 java logback mdc spring-boot

这是我用来向标头添加过滤器并添加 UUID 的代码

@Slf4j
public class ReqTxIdFilterImpl implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        List<String> headerNames = Collections.list(request.getHeaderNames());
        String requestTxId = "";
        if(!headerNames.isEmpty()){
            requestTxId = request.getHeader(
                    headerNames.stream()//
                            .filter(header -> header.contains("txId"))
                            .findAny()
                            .orElse("")//
                    );
        }
        if (StringUtils.isEmpty(requestTxId)) {
            requestTxId = UUID.randomUUID().toString();
        }
        MDC.put("txId", requestTxId);
        filterChain.doFilter(servletRequest, servletResponse);
        MDC.clear();
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用 spring boot 和 MockMvc 来测试 API

@Autowired
    private MockMvc mockMvc;

    @Test
    public void test_generatePolicyNumber() throws Exception {
        MvcResult mvcResult = this.mockMvc.perform(post("/test"))
                .header("txId", "test-id")
                .andDo(print()).andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
                .andReturn();
        Assert.assertTrue(mvcResult.getResponse().getContentAsString().contains("test"));
    }
Run Code Online (Sandbox Code Playgroud)

我还想检查 MDC 上下文并检查此test-id是否在 MDC 上下文映射中设置为 txId 并验证它。是否可以 ?

Vla*_*can 1

你想要做的事情有点复杂,但一个可能的解决方案是使用参数捕获器。

例如:

public class ReqTxIdFilterImpl implements Filter {

    @Override
    public void doFilter(...) {
       // rest of code
       addIdToMdc(requestTxId);
       filterChain.doFilter(servletRequest, servletResponse);
       MDC.clear();
    }

    protected void addIdToMdc(String requestTxId) { 
       MDC.put("txId", requestTxId);  
    }
}
Run Code Online (Sandbox Code Playgroud)

在测试类中:

    @Test
    public void test_generatePolicyNumber() throws Exception {
      ...
      ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
      Mockito.verify(filter).addIdToMdc(captor.capture());

      //get the String object added to MDC using ArgumentCaptor
      String actual = captor.getValue();
      Assert.assertThat(actual).isEqualTo(expectedId);
   }
Run Code Online (Sandbox Code Playgroud)

请注意,您需要在 TestClass 中注入过滤器,我不确定这在您的情况下是否可行。

另一种解决方案是提取将该 Id 组合到另一个组件中的逻辑并测试该类或为其调用ResultCaptor。:/sf/answers/1798589971/