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

MockK模拟UUID静态类时直接调用randomUUID()出现权限错误的解决方案咨询

MockK模拟UUID静态类时直接调用randomUUID()出现权限错误的解决方案咨询

你遇到的这个权限错误是Java 9+模块化系统导致的:java.base模块没有将java.util包的私有成员开放给测试所在的未命名模块,而MockK在尝试mockUUID.randomUUID()并返回UUID实例时,需要调用到UUID内部的私有静态方法parse4Nibbles,从而触发了这个访问限制。

下面给你两种可行的解决方案:

方案一:预先构建UUID实例,mockrandomUUID()直接返回实例

这种方式不需要修改VM参数,而是提前准备好合法的UUID实例,让MockK直接返回这些实例,避免触发UUID内部的私有方法访问。

你可以用UUID.fromString()方法创建合法的UUID实例(只要字符串符合UUID格式即可),示例代码如下:

// 预先准备UUID实例列表
val uuidSource = listOf(
    UUID.fromString("550e8400-e29b-41d4-a716-446655440000"),
    UUID.fromString("550e8400-e29b-41d4-a716-446655440001"),
    UUID.fromString("550e8400-e29b-41d4-a716-446655440002")
)

@Test
fun x1() {
    mockkStatic(UUID::class)
    // 直接mock randomUUID()返回预先准备的实例
    every { UUID.randomUUID() } returnsMany uuidSource
    
    listOf(1, 2, 3).forEach { _ ->
        println(UUID.randomUUID())
    }
}

方案二:添加VM参数开放模块访问权限

如果需要动态生成UUID实例而不是硬编码字符串,可以通过添加JVM参数,让java.base模块开放java.util包的私有成员给未命名模块。

Gradle配置方式

在你的build.gradle.kts(或build.gradle)中给测试任务添加JVM参数:

tasks.test {
    jvmArgs("--add-opens", "java.base/java.util=ALL-UNNAMED")
}

IntelliJ运行配置方式

在IntelliJ的测试运行配置中,找到"VM options"栏,添加:

--add-opens java.base/java.util=ALL-UNNAMED

补充说明:为什么链式调用toString()没问题?

你之前测试中every { UUID.randomUUID().toString() } returnsMany uuidSource能正常工作,是因为MockK只拦截了toString()方法的调用,并没有真正mockrandomUUID()返回UUID实例——它相当于在一个"虚拟"的UUID对象上mock了toString()的返回值,不会触发UUID内部的私有方法访问,因此避开了模块化权限限制。

备注:内容来源于stack exchange,提问作者Lopamudra Rath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 15:59:37