I'm trying to test a Flow that uses shareIn with Turbine, but I'm a bit lost why my tests are failing and how I can fix it.
class MyTest {
private val scope = CoroutineScope(Dispatchers.Default)
private val mutableSharedFlow = MutableSharedFlow<Int>()
@Test
fun succeeds() = runBlocking {
val sharedFlow = mutableSharedFlow
sharedFlow.test {
expectNoEvents()
mutableSharedFlow.emit(3)
expect(expectItem()).toBe(3)
}
}
@Test
fun fails() = runBlocking {
val sharedFlow = mutableSharedFlow
.shareIn(scope, started = SharingStarted.WhileSubscribed())
sharedFlow.test {
expectNoEvents()
mutableSharedFlow.emit(3)
expect(expectItem()).toBe(3)
}
}
}
In these tests, the first succeeds() test runs fine, but as soon as I include shareIn in the fails() test, the test fails with a timeout:
Timed out waiting for 1000 ms
kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
(Coroutine boundary)
at app.cash.turbine.ChannelBasedFlowTurbine$expectEvent$2.invokeSuspend(FlowTurbine.kt:238)
at app.cash.turbine.ChannelBasedFlowTurbine$withTimeout$2.invokeSuspend(FlowTurbine.kt:206)
at app.cash.turbine.ChannelBasedFlowTurbine.expectItem(FlowTurbine.kt:243)
What should I do to test flows that use shareIn?
I do not know why you've decided to use a scope with
Dispatchers.Defaultas here:For tests, just use
Dispatchers.Unconfinedinstead because it executes coroutines immediately on the current thread and that's exactly what you need there.So, after applying the change above, both of your tests passed successfully.
You can find my sample project for this question here.