How can you use runBlockingTest with a coroutine you do not cancel?
See original GitHub issueIn my test code, I have an ongoing actor
coroutine that I do not need to directly cancel - I rely on the coroutine scope to cancel it. The below is a simplified example of my production code, which does not directly expose the actor coroutine to test code, so I cannot directly cancel it (obviously, calling actor.close()
allows the test to pass).
@Test
fun runBlocking_() = runBlocking<Unit> {
val emittedNumbers = mutableListOf<Int>()
val actor = actor<Int> {
for (i in channel) {
emittedNumbers.add(i)
}
}
actor.send(1)
actor.send(2)
// fails here with:
// org.junit.ComparisonFailure:
// Expected :[1, 2]
// Actual :[1]
assertThat(emittedNumbers)
.isEqualTo(listOf(1, 2))
}
@Test
fun runBlockingTest_() = runBlockingTest {
val emittedNumbers = mutableListOf<Int>()
val actor = actor<Int> {
for (i in channel) {
emittedNumbers.add(i)
}
}
actor.send(1)
actor.send(2)
assertThat(emittedNumbers)
.isEqualTo(listOf(1, 2))
// fails here with:
// kotlinx.coroutines.test.UncompletedCoroutinesError: Test finished with active jobs:
}
Looking at cleanupTestCoroutines()
- it says
@throws UncompletedCoroutinesError if any pending tasks are active, however it will not throw for suspended coroutines.
The actor is suspended - but why does the exception still get thrown? Note - I also tried calling cleanupTestCoroutines
inside the runBlockingTest
lambda, but still no luck. Am I doing something wrong?
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (4 by maintainers)
Top Results From Across the Web
Unit testing coroutines runBlockingTest: This job has not ...
Don't use flow.collect directly inside runBlockingTest . It should be wrapped in launch; Don't forget to cancel TestCoroutineScope in the ...
Read more >runBlockingTest - Kotlin
This method requires that all coroutines launched inside testBody complete, or are cancelled, as part of the test conditions. Unhandled exceptions thrown by ......
Read more >Unit Testing with Kotlin Coroutines: The Android Way - Medium
What will we learn? Testing suspend functions with runBlocking() and runBlockingTest(); Test Coroutines running on Dispatchers.
Read more >Unit Testing Coroutine Suspend Functions using ... - craigrussell
This feels like it should work, and I don't know why it doesn't. Maybe it's a bug in the current implementation of runBlockingTest...
Read more >Kotlin coroutine unit testing the better way - LogRocket Blog
If you are programming in Kotlin, you most likely use coroutines for ... inside the coroutine are not propagated as test failures, we'll ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This actually doesn’t work as you can’t cancel a
TestCoroutineScope
, it throws an exceptionI’d also expect the scope to cancel when runBlockingTest lambda completes