Java中Mockito单元测试报错求助(Mockito1.10.19+Java18)
依赖版本
- Mockito版本:mockito-all-1.10.19
- Java版本:"18" 2022-03-22
- JUnit版本:4
相关代码
UserDao 接口
package fita.application; public interface UserDao { boolean createUser(String email); }
UserService 接口
package fita.application; public interface UserService { String createUser(String email); }
UserServiceImpl 实现类
package fita.application; public class UserServiceImpl implements UserService{ private UserDao userDao; public UserServiceImpl(UserDao userDao) { this.userDao = userDao; } @Override public String createUser(String email) { boolean rs = this.userDao.createUser(email); return rs ? "SUCCESS" : "FAILED"; } }
UserServiceImplTest 测试类
package fita.junittest; import org.junit.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import fita.application.UserDao; import fita.application.UserService; import fita.application.UserServiceImpl; @RunWith(MockitoJUnitRunner.class) public class UserServiceImplTest { @Mock private UserDao userDao; private UserService userService; @Before public void setUp() throws Exception { userService = new UserServiceImpl(userDao); } @After public void tearDown() throws Exception { userService = null; } @Test public void createUser_WhenEmailExisted_ReturnFailed() { Mockito.when(userDao.createUser("thuanhieu02")).thenReturn(false); Assert.assertEquals("FAILED", userDao.createUser("thuanhieu02")); } @Test public void createUser_WhenEmailNotExisted_ReturnSuccess() { Mockito.when(userDao.createUser("thuanhieu03")).thenReturn(true); Assert.assertEquals("SUCCESS", userDao.createUser("thuanhieu03")); } }
测试报错栈
java.lang.ExceptionInInitializerError at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167) at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217) at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145) at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117) at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109) at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105) at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70) at org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95) at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57) at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49) at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24) at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) at org.mockito.Mockito.mock(Mockito.java:1285) at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33) at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16) at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43) at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66) at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71) at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55) at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108) at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27) at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:319) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @48140564 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:200) at java.base/java.lang.reflect.Method.setAccessible(Method.java:194) at org.mockito.cglib.core.ReflectUtils$2.run(ReflectUtils.java:57) at java.base/java.security.AccessController.doPrivileged(AccessController.java:318) at org.mockito.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:47) ... 43 more
问题求助
我用上述版本的依赖编写了代码和测试类,执行测试后出现了上面的错误。已经在谷歌、YouTube搜索过相关解决方案,但没找到匹配的情况,希望能得到帮助。
解决方案
1. 核心原因
你用的Mockito 1.10.19是2015年的老旧版本,完全不支持Java 9及以上的模块化系统。Java 18的模块访问控制机制会阻止Mockito底层的CGLIB库反射访问java.lang.ClassLoader的方法,直接导致报错。
2. 具体解决步骤
(1)升级Mockito版本
替换成支持Java 18的Mockito版本,推荐用4.x或5.x系列。如果坚持用JUnit 4,以Maven为例,引入以下依赖:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
注意:不要再用mockito-all,这个包已经被官方废弃,现在推荐拆分后的mockito-core等独立包。
(2)修复测试类逻辑错误
你的测试方法里犯了一个低级错误:要测试的是UserServiceImpl的业务逻辑,应该调用userService.createUser(),而不是直接调用Mock对象userDao.createUser()。修改后的测试方法如下:
@Test public void createUser_WhenEmailExisted_ReturnFailed() { Mockito.when(userDao.createUser("thuanhieu02")).thenReturn(false); Assert.assertEquals("FAILED", userService.createUser("thuanhieu02")); } @Test public void createUser_WhenEmailNotExisted_ReturnSuccess() { Mockito.when(userDao.createUser("thuanhieu03")).thenReturn(true); Assert.assertEquals("SUCCESS", userService.createUser("thuanhieu03")); }
(3)可选:升级到JUnit 5(推荐)
如果条件允许,建议升级到JUnit 5,它对Java 8+的支持更完善,配合最新Mockito使用更顺畅。此时测试类的注解需要调整:
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(MockitoExtension.class) public class UserServiceImplTest { @Mock private UserDao userDao; private UserService userService; @BeforeEach public void setUp() throws Exception { userService = new UserServiceImpl(userDao); } @AfterEach public void tearDown() throws Exception { userService = null; } // 测试方法同上 }
内容的提问来源于stack exchange,提问作者dthieu2002
相关产品推荐
相关产品推荐

