1

我正在尝试测试shareIn与 Turbine 一起使用的 Flow,但我有点迷失为什么我的测试失败以及如何修复它。

class MyTest {

    private val scope = CoroutineScope(Dispatchers.Default)
    private val mutableSharedFlow = MutableSharedFlow<Int>()

    @Test
    fun succeeds() = runBlocking {
        val sharedFlow = mutableSharedFlow

        sharedFlow.test {
            expectNoEvents()
            mutableSharedFlow.emit(3)
            expect(expectItem()).toBe(3)
        }
    }

    @Test
    fun fails() = runBlocking {
        val sharedFlow = mutableSharedFlow
            .shareIn(scope, started = SharingStarted.WhileSubscribed())

        sharedFlow.test {
            expectNoEvents()
            mutableSharedFlow.emit(3)
            expect(expectItem()).toBe(3)
        }
    }
}

在这些测试中,第一个succeeds()测试运行良好,但是一旦我包含shareInfails()测试中,测试就会因超时而失败:

Timed out waiting for 1000 ms
kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
    (Coroutine boundary)
    at app.cash.turbine.ChannelBasedFlowTurbine$expectEvent$2.invokeSuspend(FlowTurbine.kt:238)
    at app.cash.turbine.ChannelBasedFlowTurbine$withTimeout$2.invokeSuspend(FlowTurbine.kt:206)
    at app.cash.turbine.ChannelBasedFlowTurbine.expectItem(FlowTurbine.kt:243)

我应该怎么做来测试使用的流程shareIn

4

1 回答 1

2

我不知道你为什么决定在Dispatchers.Default这里使用范围:

...
private val scope = CoroutineScope(Dispatchers.Default)
...

对于测试,只需使用它,Dispatchers.Unconfined因为它会立即在当前线程上执行协程,而这正是您所需要的。

...
private val scope = CoroutineScope(Dispatchers.Unconfined)
...

因此,在应用上述更改后,您的两个测试都成功通过了。

您可以在此处找到我针对此问题的示例项目。

于 2021-04-12T16:46:15.143 回答