【问题标题】:How do I start the application only once when testing in Ktor, instead of once per test?如何在 Ktor 中测试时只启动一次应用程序,而不是每次测试一次?
【发布时间】:2022-09-28 18:05:34
【问题描述】:
我一直在尝试为我的 Ktor 应用程序编写一些测试,并遵循此处的文档:
https://ktor.io/docs/testing.html#end-to-end
...并使用这样的测试设置:
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.testing.*
import kotlin.test.*
class ApplicationTest {
@Test
fun testRoot() = testApplication {
val response = client.get(\"/\")
assertEquals(HttpStatusCode.OK, response.status)
assertEquals(\"Hello, world!\", response.bodyAsText())
}
}
问题是,当在每个测试中使用testApplication 时,当我有大约 220 个应该运行的测试时测试会崩溃,因为我的应用程序每次启动都会读取一个 json 文件 - 导致“打开的文件太多” \“ 错误。
我想要做的是运行应用程序一次,然后将我所有的 200 多个 HTTP 请求发送到这个应用程序的单个实例,然后关闭应用程序。
相反,上面发生的是应用程序在 200 多个测试中的每一个都被启动和关闭,从而导致内存错误。
如何只运行一次应用程序?
标签:
kotlin
testing
junit
server
ktor
【解决方案1】:
解决了!
我们可以在beforeAll 函数中启动应用程序,而不是在每次测试中启动它。这是一个如何做到这一点的例子:
import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.testing.*
import io.ktor.test.dispatcher.*
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
class MyApiTest {
lateinit var JSON: Json
@Test
fun `Test some endpoint`() = testSuspend {
testApp.client.get("/something").apply {
val actual = JSON.decodeFromString<SomeType>(bodyAsText())
assertEquals(expected, actual)
}
}
companion object {
lateinit var testApp: TestApplication
@JvmStatic
@BeforeAll
fun setup() {
testApp = TestApplication { }
}
@JvmStatic
@AfterAll
fun teardown() {
testApp.stop()
}
}
}