2

I updated Kotlin coroutines to v1.6.0 and while addressing the changes in the tests I stumbled upon an issue when trying to test intermediate emissions. There's a section in the migration guide describing how to go about writing this kind of test, but the proposed solution is not fully working and I'd like to understand where's my mistake.

In particular, I have a StateFlow that gets updated twice in a coroutine launched in the viewModelScope (which internally uses Dispatchers.Main.immediate). However, when testing, the intermediate emission is not collected.

Simplified example:

class VM : ViewModel() {
    val stateFlow = MutableStateFlow("a")

    fun foo() {
        viewModelScope.launch {
            stateFlow.value = "b"
            // [...] call to a suspend fun
            stateFlow.value = "c"
        }
    }
}

class AbcTest {
    @Test
    fun testFlow() {
        Dispatchers.setMain(UnconfinedTestDispatcher())
        runTest {
            val vm = VM()
            val values = mutableListOf<String>()
            val job = launch(UnconfinedTestDispatcher(testScheduler)) {
                vm.stateFlow.collect(values::add)
            }
            vm.foo()
            job.cancel()

            assertEquals(listOf("a", "b", "c"), values)
        }
        Dispatchers.resetMain()
    }
}

This test fails with: expected: <[a, b, c]> but was: <[a, c]>.

What am I missing?

gpunto
  • 2,573
  • 1
  • 14
  • 17
  • Try to add some delay when using suspend function in VM, like this https://github.com/Kotlin-Android-Open-Source/MVI-Coroutines-Flow/blob/8ededadebed0eb46fc46f427cbcf8ef36d650b4b/mvi/mvi-testing/src/main/java/com/hoc/flowmvi/mvi_testing/BaseMviViewModelTest.kt#L46 – Petrus Nguyễn Thái Học Mar 03 '22 at 19:15
  • Hey, have a look here https://stackoverflow.com/a/72854091/5040556 – Daniele Jul 04 '22 at 08:56

0 Answers0