0

I have created a simple Micronaut Kotlin Coroutines example want to write tests with kotlin-corotines-test. I have added the kotlin-corotines-test in dependencies.

I tried to use runBlockingTest, and the following test(Kotest/FuncSpec) failed.

@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"
    }
}

And throw exceptions like this.

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)

But if use runBlocking in the fun body, it works.

@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"
        }
    }
}

Update: get the solution from issue Kotlin/kotlinx.coroutines#1204, update to kotlin coroutine to 1.6.0-RC to resolve it, and use runTest instead of the deprecated runBlockingTest.

Hantsy
  • 8,006
  • 7
  • 64
  • 109

1 Answers1

0

This is a known issue and you can check here.

Just to document it here as well, there are few workarounds as:

  • Use InstantTaskExecutorRule
@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()
  • Use runBlocking
@Test
fun test() = runBlocking {
    coroutineJob.join()
}
  • Make sure you call from your test dispatcher instance
coroutineRule.testDispatcher.runBlockingTest{...}
Aris
  • 984
  • 8
  • 22