-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Closed
Description
What is the preferred way of unit testing classes which internally launch a never-ending coroutine such as SharedFlow
collection?
Let’s say:
class MyClass(coroutineScope: CoroutineScope, flowToCollect: Flow<Int>) {
var lastObservedResult: Int? = null
init {
coroutineScope.launch {
flowToCollect.collect { lastObservedResult = it }
}
}
}
If I use runTest
and pass the created TestScope
then the test is going to fail after some time because there is a running coroutine.
@Test
fun testMyClass() = runTest {
MyClass(this, flow)
// do something here, make some assertions etc.
// at the end, the test is going to fail because of the running coroutine
}
After waiting for 60000 ms, the test coroutine is not completing, there were active child jobs (...)
So should I create another scope instead? Like this, for example?
val dispatcher = UnconfinedTestDispatcher()
@Test
fun testMyClass() = runTest(dispatcher) {
val additionalScope = CoroutineScope(dispatcher)
MyClass(additionalScope, flow)
// do something here, make some assertions etc.
additionalScope.close() // Is this necessary, btw? Is the launched coroutine going to leak after the test is finished or something?
}
I'm trying to figure out what are the best practices in such cases.