You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:20:23