Mockito无法Mock任何对象求助:Mock集合类均报错
问题:Mockito无法Mock任何对象(包括ConcurrentHashMap、ArrayList等)
我是单元测试新手,尝试用Mockito Mock一个Map,结果Mock ConcurrentHashMap时出错,而且所有对象都Mock失败。
测试代码
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.concurrent.ConcurrentHashMap; import static org.mockito.Mockito.mock; class UtilsTest { @BeforeEach void setUp() { ConcurrentHashMap mockedMap = mock(ConcurrentHashMap.class); } @Test void lessLoadedServersCount(){ } }
报错信息
JDK 11下的报错
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: class java.util.concurrent.ConcurrentHashMap. Mockito can only non-private & non-final classes. If you're not sure why you're getting this error, please report to the mailing list. Java : 11 JVM vendor name : OpenLogic JVM vendor version : 11.0.19+7-adhoc.admin.jdk11u JVM name : OpenJDK 64-Bit Server VM JVM version : 11.0.19+7-adhoc.admin.jdk11u JVM info : mixed mode OS name : Mac OS X OS version : 13.2.1 Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
更换为JDK 19后的报错
Mock ArrayList时:
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: class java.util.ArrayList. Mockito can only non-private & non-final classes. If you're not sure why you're getting this error, please report to the mailing list.
Mock HashSet时:
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: class java.util.HashSet. Mockito can only non-private & non-final classes. If you're not sure why you're getting this error, please report to the mailing list.
解决方案
检查Mockito版本兼容性
确保Mockito版本与JDK版本匹配:JDK 11+需用Mockito 3.3.0及以上,JDK 19需用Mockito 4.5.0及以上。更新依赖示例:
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>Gradle:
testImplementation 'org.mockito:mockito-core:4.11.0' testImplementation 'org.mockito:mockito-junit-jupiter:4.11.0'优先Mock接口而非具体类
不要直接MockConcurrentHashMap、ArrayList这类具体类,改为Mock它们的接口Map、List、Set,既符合面向接口原则,也能规避Mockito对具体类的Mock限制:Map<String, Object> mockedMap = mock(Map.class); List<String> mockedList = mock(List.class); Set<String> mockedSet = mock(Set.class);添加Mockito-inline依赖(针对必须Mock具体类的场景)
如果确实需要Mock具体类,添加mockito-inline依赖,它支持Mock final类、静态方法,解决JDK模块系统带来的限制:
Maven:<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>Gradle:
testImplementation 'org.mockito:mockito-inline:4.11.0'配置JVM参数
针对JDK 9+,在测试运行配置中添加--add-opens java.base/java.util=ALL-UNNAMED参数,确保Mockito能访问java.util包的内部类。
内容的提问来源于stack exchange,提问作者MohanaSundaram J
相关产品推荐
相关产品推荐

