Vic*_*lyk 5 testing kotlin kotest
我正在使用 Kotests 为 Ktor 应用程序编写测试,但偶然发现了如何在全局范围内更改测试的环境变量的问题。我尝试过添加withEnvironment,但它给我带来了非常奇怪的错误
Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @3daa422a
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @3daa422a
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
Run Code Online (Sandbox Code Playgroud)
我的测试文件看起来像这样
class VisitorSpec : FreeSpec({
val ds = createDataSourceTest()
val visitor = RegisterVisitorDTO(
email = TestConstants.VISITOR_EMAIL,
username = TestConstants.VISITOR_USERNAME,
password = TestConstants.PASSWORD,
firstName = TestConstants.VISITOR_FIRST_NAME,
lastName = TestConstants.VISITOR_LAST_NAME,
gender = TestConstants.VISITOR_GENDER,
birthday = TestConstants.VISITOR_BIRTHDAY,
)
"check visitor routes" - {
val loginData = LoginDTO(TestConstants.VISITOR_EMAIL + 0, TestConstants.PASSWORD)
"can get list of visitors with correct query" {
withEnvironment(
mapOf(
"POSTGRES_URL" to "jdbc:postgresql://localhost:5432/test",
"POSTGRES_USERNAME" to "test_user",
"POSTGRES_PASSWORD" to "test_pass"
)
) {
testApplication {
val client = getClient(ds)
repeat(6) {
registerConfirmedUser(
client, visitor.copy(
email = "${TestConstants.VISITOR_EMAIL}$it",
username = "${TestConstants.VISITOR_USERNAME}$it",
)
)
}
val accessToken = loginUser(client, loginData).run { this.body<LoginResponseDTO>().accessToken }
client.get("/api/v1/visitors?page=1&count=5") {
header("Authorization", "Bearer $accessToken")
}.apply {
val response = this.body<VisitorPaginatedResponseDTO>()
response.data.size.shouldBe(5)
response.totalCount.shouldBe(6)
response.currentPage.shouldBe(1)
}
}
}
}
...
Run Code Online (Sandbox Code Playgroud)
如果我删除
withEnvironment(
mapOf(
"POSTGRES_URL" to "jdbc:postgresql://localhost:5432/test",
"POSTGRES_USERNAME" to "test_user",
"POSTGRES_PASSWORD" to "test_pass"
)
)
Run Code Online (Sandbox Code Playgroud)
它会正常工作,但使用默认数据库,对此有什么建议吗?
在某些地方,建议使用
override fun listeners() = listOf(
SystemEnvironmentTestListener("fooKeyEnv", "barValueEnv"),
SystemPropertyTestListener("fooKeyProp", "barValueProp")
)
Run Code Online (Sandbox Code Playgroud)
但 ide 告诉我这个方法已被弃用。预先感谢您的任何建议。
最新的 Java 版本禁止使用默认访问设置修改环境变量(JEP 403:强封装 JDK 内部)。Kotest和其他一些操作环境变量的测试框架受此影响,您可以找到相关问题:
一种解决方案是将参数添加到运行测试的 JVM,这将使 Java 平台模块系统允许访问测试框架使用的 API。这是解释这些论点的答案: How to set environment variable in Java without 'illegal reflecting access'? 如何使用附加打开?
如果您没有在代码中使用 Java 模块,则该参数的最简单形式是:
--add-opens java.base/java.util=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)
如果您使用 Gradle 运行测试,那么您可以将此参数传递给jvmArgs任务的test:
--add-opens java.base/java.util=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)
注意:即使某些代码需要非法访问 JDK 内部,以这种方式修改模块访问也可以使测试通过。确保您的代码不会执行此操作,或者您有其他测试来检查此情况而不修改模块访问权限。
似乎其他一些库(例如 )system-stubs提供了一种在测试中修改环境变量的方法,而无需对 JDK 内部进行非法反射访问。
| 归档时间: |
|
| 查看次数: |
1856 次 |
| 最近记录: |