Kotlin state flows not emitting in unit test with view model scope

Viewed 557

I'm new to Kotlin Coroutines and Flows and unit testing them. I have a pretty simple test:

@Test
fun debounce(): Unit = runBlocking {
    val state = MutableStateFlow("hello")
    val debouncedState = state.debounce(500).stateIn(this, SharingStarted.Eagerly, "bla")

    assertThat(debouncedState.value).isEqualTo("bla")

    state.value = "good bye"

    // not yet...
    assertThat(debouncedState.value).isEqualTo("bla")

    delay(600)

    // now!
    assertThat(debouncedState.value).isEqualTo("good bye")

    // cannot close the state flows :(
    cancel("DONE")
}

It works just fine (except that I cannot stop it, but that's a different issue).

Next, I want to test my ViewModel which includes the exact same state flows. It's basically the same code above, but I thought it should run in the same scope as viewModel.someMutableStateFlow so I tried to run it on viewModelScope:

@Test
fun debounce(): Unit = runBlocking {
    val viewModel = MyViewModel()

    // in view model the state and debouncedState are defined the same way as above
    val state = viewModel.someMutableStateFlow
    val debouncedState = state.debounce(500).stateIn(viewModel.viewModelScope, SharingStarted.Eagerly, "bla")

    ///////////////////////////////////////////////////
    // Below is the same code as in previous example //
    ///////////////////////////////////////////////////

    assertThat(debouncedState.value).isEqualTo("bla")

    state.value = "good bye"

    // not yet...
    assertThat(debouncedState.value).isEqualTo("bla")

    delay(600)

    // now!
    assertThat(debouncedState.value).isEqualTo("good bye")

    // cannot close the state flows :(
    cancel("DONE")
}

But this time the debouncedState.value is never changed, it stays bla all the time! Nothing is emitted from those states.

Does this have something to do with the fact that I am using viewModelScope and maybe it is not running?

Some explanation about what's going on here would be great.

0 Answers
Related