Mockito 2与JUnit 5异常问题:无法Mock类的现象排查
我来帮你排查下Mockito无法Mock类的常见原因和对应的解决办法,结合你的测试场景来看:
你提到Mock接口是正常的,说明Mockito和JUnit 5的基础集成没问题,问题大概率出在MockedJavaClass本身的特性或者Mockito的特定配置上,我们逐一排查:
1. 检查MockedJavaClass是否为final类
Mockito默认通过动态生成子类的方式创建Mock对象,而final类无法被继承,自然没法生成Mock子类。如果你的MockedJavaClass是final的,这就是问题根源。
解决办法:
- 若有权修改类代码,去掉
final修饰符; - 若不能修改类,可开启Mockito的final类Mock支持:在
src/test/resources/mockito-extensions目录下创建名为org.mockito.plugins.MockMaker的文件,文件内容仅写一行:mock-maker-inline。
2. 检查类是否有可访问的无参构造函数
Mockito创建Mock对象时,默认会调用类的无参构造函数初始化子类实例。如果MockedJavaClass没有无参构造,或所有构造函数都是private/protected且测试代码无法访问,就会导致Mock失败。
解决办法:
- 给
MockedJavaClass添加一个public的无参构造函数; - 若必须带参数构造,可指定构造参数创建Mock:
final MockedJavaClass mock = mock(MockedJavaClass.class, withSettings().useConstructor(构造参数1, 构造参数2));
3. 确认Mockito与JUnit 5的依赖版本兼容
Mockito 2的部分早期版本和JUnit 5的MockitoJavaExtension可能存在兼容性问题,且要确保Mockito核心库和JUnit Jupiter扩展库的版本一致,避免版本不匹配导致异常。
比如Maven项目可使用如下兼容的稳定版本依赖:
<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>
4. 检查是否启用了Java模块系统(JPMS)
如果你的项目用了Java 9+的模块系统(存在module-info.java),需确保Mockito能访问到要Mock的类所在模块,否则无法生成动态代理。
解决办法:
在module-info.java中对Mockito开放模块访问:
module your.module.name { opens com.your.package containing.MockedJavaClass to org.mockito.core; }
5. 检查类的访问修饰符
如果MockedJavaClass是包级私有(默认访问修饰符,无public),而测试类不在同一个包下,Mockito可能无法生成该类的子类。
解决办法:
- 将测试类移到和
MockedJavaClass同一个包下; - 把
MockedJavaClass改为public访问修饰符; - 或用
@VisibleForTesting注解标记类(需引入Guava或AndroidX相关依赖),允许测试代码访问包级类。
你可以先从第一个原因(是否为final类)开始排查,这是Mock类失败最常见的诱因。
内容的提问来源于stack exchange,提问作者Sam Clarenc

