【发布时间】:2023-03-22 18:34:02
【问题描述】:
我的 KMM 项目测试在新范围内异步启动的 ktor 客户端请求时遇到问题。出于测试目的,我传入Dispatchers.Unconfined 作为新范围的上下文(在实际生产代码中我使用newSingleThreadContext())。
我在下面创建了一个非常简化的悬挂 ktor 请求版本:
@ExperimentalCoroutinesApi
@Test
fun testExample(): Unit {
val scope = CoroutineScope(Dispatchers.Unconfined)
scope.launch {
val client = HttpClient { BrowserUserAgent() }
// This line hangs
val response : HttpResponse = client.get("https://google.com")
// Will never get here
println("Response: $response")
fail("This test should fail")
}
}
请注意,如果您不在 CoroutineScope.launch 中调用,那么它可以正常工作。然后挂起/冻结仅在 CoroutineScope.launch 中调用时发生。同样,这是一个极其简化的示例,但在我的实际代码中,以这种方式设置它的原因是,我可以在最终发出 ktor 请求之前在后台线程中处理一些数据 - 因此是 CoroutineScope.launch。另请注意,我的代码在 iOS 模拟器上运行时似乎运行良好。 只有在作为单元测试运行时才会挂起。
我是否遗漏了一些东西来完成这项工作,或者这是一个错误?
【问题讨论】:
-
在我的机器上,您的测试在 iosX64 和 linuxX64 目标上使用 Ktor 1.6.4 或 1.6.5 通过。你能描述一下你运行这个测试的环境吗?
-
对我来说测试也通过了,但这不是问题。问题是响应永远不会返回,
println("Response: $response")行永远不会打印。我编辑了代码示例以添加fail()语句,以便测试用例应该失败 - 但是在我的机器上它仍然通过。在 MacOS 上运行,目标为 android 和 iosX64,ktor v1.6.5,kotlin v1.5.31,kotlinx-coroutines-core v1.5.2-native-mt。 -
这是预期的行为,因为
launch块中的代码是异步执行的。由于您没有明确等待其完成,因此永远不会打印响应。换句话说,您的测试在后台作业之前完成了它的执行。
标签: kotlin-coroutines ktor kotlin-multiplatform-mobile