Hi team, hope you don’t mind a Cashapp/Turbine question here.
This is a cross-post from #coroutines b/c I’m not quite sure if Turbine is influencing the outcome here..
I’m having trouble with a unit test. I’m trying to validate the behaviour of a StateFlow. But, the StateFlow is only in this particular state until a certain suspend function completes.
During testing, my test double uses a delay to simulate a long running task. But, due to the nature of
runBlockingTest()
, this delay is skipped, so this function completes immediately, and the StateFlow essentially bypasses the value I’m trying to test.
Tim Malseed
12/30/2021, 10:33 PM
Copy code
sealed class ViewState {
object None : ViewState()
object Loading : ViewState()
object Some : ViewState()
}
class Foo {
val viewState = MutableStateFlow<ViewState>(ViewState.None)
fun updateViewState() {
viewState.value = ViewState.Loading
viewState.value = someLongRunningOperation()
}
private suspend fun somePotentiallyLongRunningOperation(): ViewState {
delay(5000)
return ViewState.Some
}
}
@Test
fun myTest() = runBlockingTest {
foo.viewState.test {
foo.updateViewState()
assertThat(awaitItem()).isInstanceOf(ViewState.Loading::class.java) // Fails. ViewState is ViewState.Some
cancelAndConsumeRemainingEvents()
}
}
p
Paul Woitaschek
12/30/2021, 10:42 PM
As it's deprecated, try runTest first
👍 2
t
Tim Malseed
12/30/2021, 10:45 PM
The above is psuedo code, and I hadn’t actually written that exact test. Looks like it actually is working, so perhaps there’s some other problem in my production code. I need to get better at actually writing small repros.
Tim Malseed
12/30/2021, 11:29 PM
Moving to
runTest()
does seem to solve most of my problems, and revealed a few new ones that make me wonder how the tests ever passed at all!