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

Spring Boot测试Mockito报错:无法mock java.util.Random类

报错现象

运行Spring Boot单元测试时抛出org.mockito.exceptions.base.MockitoException,无法初始化@Spy注解标注的random字段,核心提示为:

Mockito cannot mock this class: class java.util.Random,Mockito仅支持mock非私有、非final类。

异常栈同时触发后续空指针抑制异常,根因追溯到IllegalAccessException:Java 17模块系统默认做了内部API强封装,Mockito依赖的byte-buddy组件无法访问java.base模块下jdk.internal.util.random包的内部注解属性,导致字节码增强失败。

运行环境
  • Java版本:17.0.3+7-LTS(Azul Systems OpenJDK 64-Bit Server VM)
  • 操作系统:Mac OS X 12.0.1
依赖版本
  • spring-boot-starter-test: 2.7.1
  • mockito-core: 4.5.1
  • byte-buddy: 1.12.11(从Spring Boot默认管理的1.12.9版本手动升级)
问题复现代码
@ExtendWith(MockitoExtension.class)
public class ChallengeGeneratorServiceTest {

  private ChallengeGeneratorService challengeGeneratorService;

  @Spy
  private Random random;

  @BeforeEach
  public void setUp() {
    challengeGeneratorService = new ChallengeGeneratorServiceImpl(random);
  }

  @Test
  public void generateRandomFactorIsBetweenExpectedLimits() {
    // 89 is max - min range
    given(random.nextInt(89)).willReturn(20, 30);

    // when we generate a challenge
    Challenge challenge = challengeGeneratorService.randomChallenge();

    // then the challenge contains factors as expected
    then(challenge).isEqualTo(new Challenge(31, 41));
  }

}
问题根因

这是Java 17环境下Mockito mock JDK内置类的已知兼容性问题。Java 17默认启用模块系统强封装规则,不允许外部组件反射访问JDK内部包的私有属性、注解,Mockito通过byte-buddy生成Random的mock子类时,需要访问jdk.internal.util.random下的内部资源,权限不足直接抛出异常,最终导致@Spy注解的字段初始化失败。

修复方案

可根据实际场景选择以下任意一种方案解决:

  • 方案1(推荐):放弃mock/spy JDK原生Random实例,直接使用真实Random对象,通过指定固定种子的方式获得可预测的随机数序列,完全绕开模块系统权限限制,代码改动最小:
// 删除@Spy注解,直接实例化并指定固定种子,即可控制nextInt的返回顺序
private Random random = new Random(1L);
  • 方案2:如果必须使用Mockito做方法桩设置、调用验证,给测试运行的JVM添加模块开放参数,放开对应JDK内部包的访问权限:
    • 若通过Maven运行测试,在pom.xml的maven-surefire-plugin配置中添加如下参数:
    <configuration>
      <argLine>--add-opens java.base/jdk.internal.util.random=ALL-UNNAMED</argLine>
    </configuration>
    
    • 若直接通过IDE运行测试,在测试类的运行配置VM options项中添加上述--add-opens参数即可。
  • 方案3:将Mockito、byte-buddy升级到完全适配Java 17模块系统的高版本,升级时注意和当前Spring Boot 2.7.1的依赖管理规则兼容,避免出现类版本冲突。

内容的提问来源于stack exchange,提问作者amritkrs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:03:31