使用环境变量时如何在 ktor 中进行测试?
Posted
技术标签:
【中文标题】使用环境变量时如何在 ktor 中进行测试?【英文标题】:How to test in ktor while using environment variables? 【发布时间】:2021-06-12 09:48:25 【问题描述】:我在我的 Ktor 项目中使用 PostgreSQL 数据库。我在 Intellij Idea 的系统环境变量中保存了 JDBC_URL、JDBC_DRIVER...。
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 EXCEPTION
测试功能:
@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)
我们如何在测试时访问环境变量,或者在使用数据库时还有其他方法可以测试吗?
【问题讨论】:
【参考方案1】:您可以引入额外的抽象级别来访问环境变量(通过为hikari
函数创建一个参数,然后在测试中传递它的参数)或在每次测试之前全局改变所需的环境变量(@987654321 @)。此外,您可以对整个 HikariDataSource
使用模拟。
【讨论】:
您好,先生,感谢您的回复。你能解释一下什么是嘲笑 这里可以找到解释devopedia.org/…。【参考方案2】:在测试中,您可以使用 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-configuration-properties-in-tests
【讨论】:
首先感谢您的回复?。我见过那种方法,但它是用于配置属性的,但我要求的是环境变量。如何在其中传递环境变量。以上是关于使用环境变量时如何在 ktor 中进行测试?的主要内容,如果未能解决你的问题,请参考以下文章