使用环境变量时如何在ktor中进行测试



我在Ktor项目中使用PostgreSQL数据库。我保存了JDBC_URL、JDBC_DRIVER。。。,Intellij Idea的系统环境变量。

fun hikari(): HikariDataSource{
val config = HikariConfig()
****config.driverClassName =  System.getenv("JDBC_DRIVER")***********
****config.jdbcUrl = System.getenv("JDBC_DATABASE_URL")*************
config.maximumPoolSize = 3
config.isAutoCommit = false
config.transactionIsolation = "TRANSACTION_REPEATABLE_READ"
val password = System.getenv("DB_PASSWORD")
if(password != null){
config.password = password
}
config.validate()
return HikariDataSource(config)
}

一切都很好。但是,当自动测试时,它在访问这些环境变量时会出现NULL POINTER异常

测试功能:

@Test
fun testUserLogin_wrongPassword_false(){
withTestApplication({
module(testing = true)
}) {
handleRequest(HttpMethod.Post,"/v1/users/login"){
addHeader("Content-Type","application/json")
setBody("""{"email": "temp","password": "temp"}""")
}.apply {
assertEquals(HttpStatusCode.BadRequest,response.status())
}
}
}

例外:

java.lang.NullPointerException
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.zaxxer.hikari.HikariConfig.attemptFromContextLoader(HikariConfig.java:899)
at com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:474)
at com.example.repository.DatabaseFactory.hikari(DatabaseFactory.kt:40)
at com.example.repository.DatabaseFactory.init(DatabaseFactory.kt:21)
at com.example.ApplicationKt.module(Application.kt:41)
at com.example.ApplicationTest$testUserLogin_wrongPassword_false$1.invoke(ApplicationTest.kt:31)
at com.example.ApplicationTest$testUserLogin_wrongPassword_false$1.invoke(ApplicationTest.kt:17)
at io.ktor.server.testing.TestEngineKt$withTestApplication$1.invoke(TestEngine.kt:67)
at io.ktor.server.testing.TestEngineKt$withTestApplication$1.invoke(TestEngine.kt)
at io.ktor.server.testing.TestEngineKt.withApplication(TestEngine.kt:49)
at io.ktor.server.testing.TestEngineKt.withApplication$default(TestEngine.kt:43)
at io.ktor.server.testing.TestEngineKt.withTestApplication(TestEngine.kt:66)
at com.example.ApplicationTest.testUserLogin_wrongPassword_false(ApplicationTest.kt:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:119)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.lang.Thread.run(Thread.java:745)

我们如何在测试时访问环境变量,或者在使用数据库时是否有其他方法可以进行测试

您可以引入一个额外的抽象级别来访问环境变量(通过为hikari函数创建一个参数,然后在测试中传递它的参数(,也可以在每次测试前全局更改所需的环境变量(https://stackoverflow.com/a/40682052/13963150)。此外,您还可以对整个HikariDataSource使用mocking。

在测试中,您可以使用MapApplicationConfig.put方法,而不是使用application.conf来定义配置属性:

withTestApplication({
(environment.config as MapApplicationConfig).apply {
// Set here the properties
put("youkube.session.cookie.key", "03e156f6058a13813816065")
put("youkube.upload.dir", tempPath.absolutePath)
}
main() // Call here your application's module
})

https://ktor.io/docs/testing.html#defining-测试中的配置特性

使用System.getEnv()时,我看到的最佳选项是在Gradle测试属性中添加这些环境变量

build.gradle.kts

...
tasks{...}
tasks.test {
environment("DB_PASSWORD", "1234_test")
environment("DB_NAME", "my_db")
}
dependencies ...

基于Ktor 2.2.3-Referec-用自定义环境测试应用程序

@Test
fun test() = testApplication {
environment {
config = MapApplicationConfig("ktor.environment" to "dev")
}
....
}

相关内容

  • 没有找到相关文章

最新更新