使用Mockito运行JUnit测试时出现NoClassDefFoundError错误如何解决?
错误原因分析
1. 核心根因:Mockito版本与JDK版本不兼容
从报错栈里的org.mockito.internal.creation.jmock.ClassImposterizer可以判断你使用的是Mockito 1.x版本,该版本仅支持JDK 8及更低版本。而你当前运行测试使用的是JDK 9+版本(报错栈中出现java.base模块化路径,符合JDK 9及以上版本的特征),旧版Mockito依赖的老旧CGLIB、ASM库无法兼容高版本JDK的字节码规范和模块化限制,导致类初始化失败,抛出NoClassDefFoundError。
2. 次要可能:依赖缺失或冲突
如果你是手动导入Jar包而非用Maven/Gradle等构建工具管理依赖,大概率缺失Mockito运行必需的objenesis、cglib、asm依赖包;也有可能是项目中引入了多个不同版本的上述依赖,产生了类加载冲突,最终导致ClassImposterizer无法正常初始化。
其他代码问题(非本次报错原因,但会导致后续测试失败)
你编写的A类usesVoidMethod方法中,catch块仅创建了RuntimeException对象但没有抛出,异常会被直接吞掉:
// 错误写法 catch (Exception e) { new RuntimeException(e); } // 修正为 catch (Exception e) { throw new RuntimeException(e); }
如果不修正,后续两个期望抛出RuntimeException的测试会执行失败。
修复方案
- 优先升级Mockito版本:将Mockito升级到2.x、4.x或最新的5.x版本,新版Mockito使用ByteBuddy替代了老旧的CGLIB实现,完美支持JDK 8~21全版本,同时
MockitoAnnotations.initMocks(this)已标记为过时,推荐使用@RunWith(MockitoJUnitRunner.class)(JUnit4)或@ExtendWith(MockitoExtension.class)(JUnit5)直接注解测试类,无需手动初始化Mock。 - 使用构建工具管理依赖:通过Maven、Gradle引入Mockito依赖,构建工具会自动导入所有必需的传递依赖,避免手动导包的缺失或冲突问题。
- 修正上述
A类的异常抛出代码。
内容的提问来源于stack exchange,提问作者Souradeep Bhattacharya
相关产品推荐
相关产品推荐

