You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot测试中Mock MDC数据遇Mockito方法调用异常问题

解决Mockito Mock MDC静态方法报错的问题

你遇到的MissingMethodInvocationException是因为MDC的get方法是静态方法,普通的Mockito mock方式没法处理静态方法调用,必须用Mockito的静态Mock特性来解决。

错误原因

MDC是SLF4J提供的静态工具类,所有方法都是静态的。你原来的mock(MDC.class)只是创建了一个MDC的实例mock,但实际代码中调用的是MDC.get("correlation-id")这种静态方法,和你mock的实例没关系,所以Mockito会认为你没有调用mock对象的方法,抛出这个错误。

解决方案

1. 先确保依赖正确

需要引入Mockito的inline依赖(支持静态mock),如果是Maven项目,在pom.xml中添加:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>4.0.0</version> <!-- 或更高兼容版本 -->
    <scope>test</scope>
</dependency>

如果是Gradle项目:

testImplementation 'org.mockito:mockito-inline:4.0.0'

2. 修改测试代码(两种方式可选)

方式一:使用@MockStatic注解
@ExtendWith(MockitoExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = TestApp.class)
public class Test {

    private MockMvc restMvc;

    @MockStatic(MDC.class) // 静态mock MDC类
    private MDC mdcMock;

    @Autowired
    private TestController testController; // 注入待测试的控制器

    @Before
    public void setUp() {
        this.restMvc = MockMvcBuilders.standaloneSetup(testController).build();    
    }       
    
    @Test
    public void testMe() throws Exception {            
        when(MDC.get("correlation-id")).thenReturn("1234");    
        // 初始化请求参数和header
        restMvc.perform(get("/assignments")
                        .headers(headers)
                        .params(reqParams)
                        .principal(token)
                        .accept(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(status().is2xxSuccessful());    
    }
}
方式二:编程式静态Mock(手动管理生命周期)

如果不想用注解,也可以用Mockito.mockStatic的返回值管理mock生命周期,推荐用try-with-resources自动关闭:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = TestApp.class)
public class Test {

    private MockMvc restMvc;

    @Autowired
    private TestController testController;

    @Before
    public void setUp() {
        this.restMvc = MockMvcBuilders.standaloneSetup(testController).build();    
    }       
    
    @Test
    public void testMe() throws Exception {            
        // try-with-resources自动关闭静态mock,避免影响其他测试
        try (MockedStatic<MDC> mockedMDC = Mockito.mockStatic(MDC.class)) {
            mockedMDC.when(() -> MDC.get("correlation-id")).thenReturn("1234");    
            // 初始化请求参数和header
            restMvc.perform(get("/assignments")
                            .headers(headers)
                            .params(reqParams)
                            .principal(token)
                            .accept(MediaType.APPLICATION_JSON))
                    .andDo(print())
                    .andExpect(status().is2xxSuccessful());    
        }
    }
}

注意点

  • 静态mock会影响测试类的全局状态,用try-with-resources或者@MockStatic配合MockitoExtension可以自动隔离不同测试方法的静态mock。
  • 如果你的Spring Boot版本较老,需要调整Mockito版本确保兼容性。

内容的提问来源于stack exchange,提问作者Harshana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:30:42