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

Scala3.2+Scalatest3.2+Java18环境下如何Mock类?

Java 18环境下Mock Scala类的解决方案

问题背景

原有Scala测试代码运行正常:

@RunWith(classOf[JUnitRunner])
class IdentitySuite extends AnyFunSuite with Matchers {
  test("No Records returned") {
    assert(true)
  }
}

添加EasyMock相关依赖后:

testing {
    suites {
        // Configure the built-in test suite
        test {
            // Use JUnit4 test framework
            useJUnit('4.13.2')
            dependencies {
                // Use Scalatest for testing our library
                implementation 'org.scalatest:scalatest_3:3.2.12'
                implementation 'org.scalatestplus:junit-4-13_3:3.2.12.0'
                implementation 'org.easymock:easymock:4.3'
                implementation 'org.scalatestplus:easymock-4-3_3:3.2.12.0'
                runtimeOnly 'org.scala-lang.modules:scala-xml_3:2.1.0'
            }
        }
    }
}

尝试创建Mock对象时触发错误:

@RunWith(classOf[JUnitRunner])
class IdentitySuite extends AnyFunSuite with Matchers {
  test("No Records returned") {
    val cds = EasyMock.createMock(classOf[CoreDataSource])
    assert(true)
  }
}

错误信息:

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 @40f9161a

无法降级到Java 15,需在Java 18环境下解决Mock问题。

解决方案

方案1:升级EasyMock到兼容高版本Java的版本

EasyMock 4.3版本对Java 9+模块系统的适配不足,升级到4.5及以上版本即可解决反射权限问题,同时同步升级对应的ScalaTestPlus集成库:

修改构建配置:

testing {
    suites {
        test {
            useJUnit('4.13.2')
            dependencies {
                implementation 'org.scalatest:scalatest_3:3.2.15.0'
                implementation 'org.scalatestplus:junit-4-13_3:3.2.15.0'
                implementation 'org.easymock:easymock:4.6'
                implementation 'org.scalatestplus:easymock-4-6_3:3.2.15.0'
                runtimeOnly 'org.scala-lang.modules:scala-xml_3:2.1.0'
            }
        }
    }
}

方案2:添加JVM启动参数解除模块访问限制

如果暂时无法升级依赖,可通过JVM参数开放模块权限,允许EasyMock进行反射操作:

在构建配置中为测试任务添加JVM参数:

testing {
    suites {
        test {
            useJUnit('4.13.2')
            jvmArgs += [
                "--add-opens=java.base/java.lang=ALL-UNNAMED",
                "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED"
            ]
            dependencies {
                implementation 'org.scalatest:scalatest_3:3.2.12'
                implementation 'org.scalatestplus:junit-4-13_3:3.2.12.0'
                implementation 'org.easymock:easymock:4.3'
                implementation 'org.scalatestplus:easymock-4-3_3:3.2.12.0'
                runtimeOnly 'org.scala-lang.modules:scala-xml_3:2.1.0'
            }
        }
    }
}

方案3:替换为适配性更好的Mock库(如Mockito)

若上述方案均不适用,可换用Mockito,它对高版本Java和Scala的兼容性更优:

修改构建配置添加Mockito依赖:

testing {
    suites {
        test {
            useJUnit('4.13.2')
            dependencies {
                implementation 'org.scalatest:scalatest_3:3.2.12'
                implementation 'org.scalatestplus:junit-4-13_3:3.2.12.0'
                implementation 'org.mockito:mockito-core:4.8.1'
                implementation 'org.scalatestplus:mockito-4-6_3:3.2.12.0'
                runtimeOnly 'org.scala-lang.modules:scala-xml_3:2.1.0'
            }
        }
    }
}

修改测试代码使用Mockito:

@RunWith(classOf[JUnitRunner])
class IdentitySuite extends AnyFunSuite with Matchers with MockitoSugar {
  test("No Records returned") {
    val cds = mock[CoreDataSource]
    assert(true)
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:18:24