我正在使用 Kotests 為 Ktor 應用程式撰寫測驗,但偶然發現了如何最好在全域范圍內更改測驗的 env 變數的問題。我嘗試添加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)
我的測驗檔案看起來像這樣
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)
}
}
}
}
...
如果我洗掉
withEnvironment(
mapOf(
"POSTGRES_URL" to "jdbc:postgresql://localhost:5432/test",
"POSTGRES_USERNAME" to "test_user",
"POSTGRES_PASSWORD" to "test_pass"
)
)
它可以正常作業,但使用默認資料庫,對此有什么建議嗎?
在某些地方,建議使用
override fun listeners() = listOf(
SystemEnvironmentTestListener("fooKeyEnv", "barValueEnv"),
SystemPropertyTestListener("fooKeyProp", "barValueProp")
)
但 ide 告訴我這種方法已被棄用。提前感謝您的任何建議。
uj5u.com熱心網友回復:
最近的 Java 版本禁止使用默認訪問設定(JEP 403: Strongly Encapsulate JDK Internals)修改環境變數。Kotest 和其他一些操縱環境變數的測驗框架都受到了影響,你可以找到相關的問題:
- https://github.com/kotest/kotest/issues/2849
- https://github.com/stefanbirkner/system-lambda/issues/23
- https://github.com/junit-pioneer/junit-pioneer/issues/509
一種解決方案是將引數添加到運行測驗的 JVM,這將使 Java 平臺模塊系統允許訪問測驗框架使用的 API。這是一個解釋這些論點的答案: 如何在沒有“非法反射訪問”的情況下在 Java 中設定環境變數?如何使用附加打開?
如果您沒有在代碼中使用 Java 模塊,則該引數的最簡單形式是:
--add-opens java.base/java.util=ALL-UNNAMED
如果您使用 Gradle 運行測驗,則可以將此引數傳遞給jvmArgs任務test:
tasks.withType<Test>().named("jvmTest") {
jvmArgs("--add-opens", "java.base/java.util=ALL-UNNAMED")
}
注意:以這種方式修改模塊訪問可以使測驗通過,即使您的某些代碼需要非法訪問 JDK 內部。確保您的代碼沒有這樣做,或者您有其他測驗可以在不修改模塊訪問權限的情況下檢查這一點。
似乎其他一些庫(例如system-stubs.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/493241.html
