How to use flowOn and launchIn methods to collect from a Kotlin SharedFlow in a test

Viewed 30

Consider the following test. test shared flow A will pass, but test shared flow B will fail.

I was under the impression that these were equivalent statements.

Why does test shared flow B fail?
Is there a way to make it pass, while still using the launchIn method?

import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Test

@OptIn(ExperimentalCoroutinesApi::class)
class SomethingTest {

    @Test
    fun `test shared flow A`() = runTest {
        val flow = MutableSharedFlow<Int>()
        val items = mutableListOf<Int>()
        val job = launch(UnconfinedTestDispatcher()) {
            flow.collect {
                items.add(it)
            }
        }
        flow.emit(1)
        assert(items.size == 1)
        job.cancel()
    }

    @Test
    fun `test shared flow B`() = runTest {
        val flow = MutableSharedFlow<Int>()
        val items = mutableListOf<Int>()
        val job = flow.onEach { items.add(it) }
            .flowOn(UnconfinedTestDispatcher())
            .launchIn(this)
        flow.emit(1)
        assert(items.size == 1)
        job.cancel()
    }
}
0 Answers
Related