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

单元测试单独运行正常,全量运行报Mockito NoSuchMethodError错误

问题根因

报错的核心原因是项目全局依赖的Mockito版本低于3.2.0:MockitoAnnotations.openMocks(Ljava/lang/Object;)Ljava/lang/AutoCloseable;是Mockito 3.2.0版本才新增的API,而Spring Boot测试组件自带的MockitoTestExecutionListener初始化Mock时会默认调用这个新API。
单独运行测试正常是因为单测运行时类路径优先加载了高版本Mockito,运行全量测试时类路径优先级变化,加载了全局低版本Mockito,因此触发方法找不到的错误。


解决方案(无需修改全局依赖版本)

方案1:保留SpringBoot测试环境,调整监听器配置

如果你的测试依赖Spring上下文(比如需要测试Spring @Cacheable 注解实现的缓存逻辑),用这个方案:

import org.springframework.test.context.TestExecutionListeners;
import org.mockito.MockitoAnnotations;
import org.junit.jupiter.api.BeforeEach;

@SpringBootTest
// 排除默认的MockitoTestExecutionListener,避免其调用高版本Mockito的API
@TestExecutionListeners(
    mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS,
    excludeListeners = org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.class
)
public class LabelCacheTest {

    @MockBean
    private LabelRepository labelRepository;

    @Autowired
    // 移除@InjectMocks注解,@MockBean已经会自动注入到Spring管理的LabelServiceImpl实例中
    private LabelServiceImpl labelService;
    
    // 手动用低版本Mockito兼容的API初始化Mock
    @BeforeEach
    public void initMocks() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test_for_Cache() {
        List<LabelDTO> resultFromDatabase = labelService.findAll();
        List<LabelDTO> resultFromCache = labelService.findAll();

        verify(labelRepository, times(1)).findAllLabels();
        assertEquals(resultFromDatabase, resultFromCache);
    }
}

方案2:改用纯Mockito单元测试,避开Spring测试组件的依赖

如果你的测试不需要依赖其他Spring组件,可以用纯Mockito测试,完全避开Spring测试监听器的调用:

import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mock;
import org.mockito.InjectMocks;

// 替换@SpringBootTest,使用纯Mockito扩展
@ExtendWith(MockitoExtension.class)
public class LabelCacheTest {

    // 替换@MockBean为纯Mockito的@Mock注解
    @Mock
    private LabelRepository labelRepository;

    // 移除@Autowired,@InjectMocks会自动将Mock注入实例
    @InjectMocks
    private LabelServiceImpl labelService;

    @Test
    public void test_for_Cache() {
        // 注意:如果你的缓存是通过Spring @Cacheable实现的,此方案下缓存切面不会生效,需使用方案1
        List<LabelDTO> resultFromDatabase = labelService.findAll();
        List<LabelDTO> resultFromCache = labelService.findAll();

        verify(labelRepository, times(1)).findAllLabels();
        assertEquals(resultFromDatabase, resultFromCache);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:36:00