Mockito在Java8运行正常,Java11下报未完成存根错误如何解决?
问题根因分析
- Mockito 1.x版本不兼容Java 9+:你当前使用的mockito-all 1.10.19属于Mockito 1.x分支,最高仅支持Java 8环境。Java 9引入的JPMS模块系统、反射访问权限限制,以及Java 11对JDK内部API的进一步封装,都会导致老版本Mockito的字节码生成、反射调用逻辑异常,直接触发你遇到的
java.lang.IllegalStateException和UnfinishedStubbingException两类错误。 - mockito-all依赖已停止维护:Mockito官方从2.x版本开始就废弃了mockito-all合并包,推荐使用拆分后的mockito-core依赖,避免第三方依赖冲突。
解决方案
最优方案:升级Mockito到兼容Java 11的版本
将原有mockito-all依赖替换为适配Java 11的mockito-core,推荐使用4.x稳定版:
<!-- 完全替换原有mockito-all依赖 --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> <!-- 若使用JUnit 5,可额外添加以下扩展依赖,简化Mock初始化 --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
可选代码适配
原有测试逻辑无需修改即可直接运行,如需适配新API规范,可做如下调整:
- 将废弃的
MockitoAnnotations.initMocks(this)替换为MockitoAnnotations.openMocks(this),可在@After方法中关闭返回的AutoCloseable资源,避免内存泄漏。 - JUnit4可添加
@RunWith(MockitoJUnitRunner.class)、JUnit5可添加@ExtendWith(MockitoExtension.class)类注解,省略手动初始化Mock的代码。
临时兼容方案(不推荐长期使用)
如果暂时无法升级Mockito版本,可在单元测试的JVM启动参数中添加以下配置,绕过Java 11的反射访问限制:
--add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED
该方案仅做临时兼容,存在后续升级Java版本再次失效的隐患,优先选择升级Mockito版本的方案。
内容的提问来源于stack exchange,提问作者FranzWagner
相关产品推荐
相关产品推荐

