android 如何在测试中使用flowOn和launchIn方法从KotlinSharedFlow收集

lb3vh1jj  于 2023-02-14  发布在  Android
关注(0)|答案(1)|浏览(214)

考虑以下测试。test shared flow A将通过,但test shared flow B将失败。
我的印象是,这两项声明是相同的。
为什么test shared flow B会失败?
有没有办法让它通过,同时仍然使用launchIn方法?

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()
    }
}
yrdbyhpb

yrdbyhpb1#

test shared flow Atest shared flow B都不能保证通过,因为这两项测试都不等待launchassert之前完成。
test shared flow A恰好通过,如果稍微延迟添加项,则会失败。
有没有办法让它通过,同时仍然使用launchIn方法?
添加advanceUntilIdle()将通过test shared flow B

@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)
    advanceUntilIdle()
    flow.emit(1)
    assert(items.size == 1)
    job.cancel()
}

相关问题