单元测试运行报org.mockito.MockitoAnnotations.openMocks方法不存在错误如何解决
Mockito openMocks 方法不存在报错修复方案
你遇到的java.lang.NoSuchMethodError: org.mockito.MockitoAnnotations.openMocks(Ljava/lang/Object;)Ljava/lang/AutoCloseable; 错误由两个核心原因导致:一是项目存在Mockito版本冲突,加载到了不包含该方法的低版本Mockito类;二是测试代码混用了Spring测试注解和Mockito注解,没有正确初始化Mock实例,同时Bean实例冲突导致缓存逻辑也无法正常验证。
可按以下步骤修复问题:
- 第一步:统一Mockito依赖版本
该方法仅在Mockito 3.2.0及以上版本提供,需要全局统一Mockito版本,排除子模块引入的低版本Mockito依赖。以Maven为例,在pom.xml的dependencyManagement中显式锁定版本:<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> - 第二步:修正测试代码的注解混用问题
你的测试目标是验证Spring缓存逻辑,因此需要使用Spring容器管理的Bean,原代码中@InjectMocks创建的实例不受Spring管理,缓存注解不会生效,同时@Mock创建的Mock对象也不会注入到Spring容器中,需要替换为Spring Boot提供的@MockBean注解,修正后的代码如下:@Import({ TextLabelServiceImpl.class }) @ExtendWith(SpringExtension.class) @ImportAutoConfiguration(classes = { CacheAutoConfiguration.class, RedisAutoConfiguration.class }) @EnableCaching public class TextLabelServiceImplCaching2Test { private UUID uuid = null; // 注入Spring管理的Service实例,缓存注解可正常生效 @Autowired private TextLabelServiceImpl itemService; @Autowired private CacheManager cacheManager; // 用@MockBean替换Spring容器中的真实Repository,自动注入到Service中 @MockBean private TextLabelTranslatableRepository translatableRepository; @MockBean private TextLabelRepository textLabelRepository; @Test void givenRedisCaching_whenFindItemById_thenItemReturnedFromCache() { // 补充Mock方法的返回值定义,示例如下: // given(translatableRepository.findAllByEntityUuid(uuid)).willReturn(预设的返回结果); TextLabelDTO itemCacheMiss = itemService.findByUuid(uuid); verify(translatableRepository, times(1)).findAllByEntityUuid(uuid); TextLabelDTO itemCacheHit = itemService.findByUuid(uuid); verify(translatableRepository, times(1)).findAllByEntityUuid(uuid); } } - 可选方案:若不需要验证Spring缓存逻辑,仅做普通单元测试,可移除Spring相关的缓存、自动配置注解,加上Mockito扩展即可,示例如下:
@ExtendWith(MockitoExtension.class) public class TextLabelServiceImplCaching2Test { private UUID uuid = null; @InjectMocks private TextLabelServiceImpl itemService; @Mock private TextLabelTranslatableRepository translatableRepository; @Mock private TextLabelRepository textLabelRepository; @Test void givenRedisCaching_whenFindItemById_thenItemReturnedFromCache() { // 测试逻辑 } }
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

