-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Trying to create a test case around a viewModel that has flows that trigger other flows while using combine() seems to be showing some weird behavior. I seemed to have narrowed it down to using the Combine() mixed with the backgroundScope in the runTest block, for some reason the combine() is detecting value changes only once and then not again.
Here is a generic example I made of the test:
@Test
fun genericTest() = runTest(UnconfinedTestDispatcher(), timeout = 15.seconds) {
val deferred = CompletableDeferred<Int>()
backgroundScope.launch {
viewModel.msf1.collectLatest { println("latest msf1: $it") }
}
backgroundScope.launch {
viewModel.msf2.collectLatest { println("latest msf2: $it") }
}
backgroundScope.launch {
viewModel.csf.collectLatest {
println("latest csf: $it")
if (it == 3) {
deferred.complete(it)
}
}
}
backgroundScope.launch {
viewModel.sf.collectLatest {
println("latest sf: $it")
if (it == 4) {
deferred.complete(it)
}
}
}
viewModel.msf1.value = 1
viewModel.msf2.value = 2
viewModel.msf2.value = 3
viewModel.msf1.value = 2
viewModel.msf2.value = 4
deferred.await()
assertEquals(4, viewModel.sf.value)
assertEquals(3, viewModel.csf.value)
}Here is the generic flows in my viewModel:
val msf1 = MutableStateFlow(0)
val msf2 = MutableStateFlow(1)
val csf = combine(msf1, msf2) { a, b -> a + b }.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5_000L),
initialValue = 0
)
val sf = msf2.mapLatest { it }.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5_000L),
initialValue = 0
)Here is my test output failure:
latest msf1: 0
latest msf2: 1
latest csf: 0
latest csf: 1
latest sf: 0
latest sf: 1
latest msf1: 1
latest msf2: 2
latest sf: 2
latest msf2: 3
latest sf: 3
latest msf1: 2
latest msf2: 4
latest sf: 4
Expected :3
Actual :1
I would expect:
The flows to update properly. I can verify these flows update correctly in app. Using the backgroundScope, mixed with the viewModelScope that my viewModel has seems to be causing the issue when mixed with combined. My other flow that does not use combine but does use the viewModelScope updates as expected. The combined flow will just never update and the test will timeout.
Not sure if I am missing something, but seems like a bug.