使用runBlockingTest{}测试Kotlin协程失败 [英] Test Kotlin Coroutines with runBlockingTest{} failed

查看:21
本文介绍了使用runBlockingTest{}测试Kotlin协程失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个简单的Micronaut Kotlin Coroutines示例,希望用kotlin-corotines-test编写测试。我已将kotlin-corotines-test添加到依赖项中。

我尝试使用runBlockingTest,但以下测试(Kotest/FuncSpec)失败。

@Test
fun `test GET all posts endpoint`() = runBlockingTest {
    val response = client.exchange("/posts", Array<Post>::class.java).awaitSingle()

    response.status shouldBe HttpStatus.OK
    response.body()!!.map { it.title }.forAny {
        it shouldContain "Micronaut"
    }
}

并引发类似的异常。

java.lang.IllegalStateException: This job has not completed yet
    at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1190)
    at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)
    at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)
    at com.example.ApplicationTest.test GET posts endpoint(ApplicationTest.kt:30)

但如果在有趣的正文中使用runBlocking,它将起作用。

@Test
fun `test GET all posts endpoint`() {
    runBlocking {
        val response = client.exchange("/posts", Array<Post>::class.java).awaitSingle()

        response.status shouldBe HttpStatus.OK
        response.body()!!.map { it.title }.forAny {
            it shouldContain "Micronaut"
        }
    }
}

更新:从问题Kotlin/kotlinx.coroutines#1204获取解决方案,将Kotlin协程更新到1.6.0-rc以解决该问题,并使用runTest而不是过时的runBlockingTest

推荐答案

这是一个已知问题,您可以检查here

为了在这里也进行记录,有几个解决方法如下:

  • 使用InstantTaskExecutorRule
@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()
  • 使用运行阻止
@Test
fun test() = runBlocking {
    coroutineJob.join()
}
  • 确保从测试调度程序实例调用
coroutineRule.testDispatcher.runBlockingTest{...}

这篇关于使用runBlockingTest{}测试Kotlin协程失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆