kotlin 如何正确地对一个只读的SharedFlow进行单元测试?

lf3rwulv  于 2023-02-09  发布在  Kotlin
关注(0)|答案(1)|浏览(120)

我在repo内部为我的SharedFlow而苦恼。因此,在真实的实现中,我有一个单例类,它订阅不同的流,进行一些操作,然后对应用中的所有其他地方执行shareIn(),作为单一的真实源(服务、虚拟机等)。因此,这是一个巨大的长链调用和设置。
当我尝试获取第一个发出的值时,我要么遇到了一个未完成的协程问题(所有其他测试在我的测试调度器中都能正常工作,所以我不认为这是调度器的问题),或者当我尝试使用sharedFlow.toList(someMutableList)时,就像我在其他示例中发现的那样,我得到了一个空的结果列表。我不能从测试中发送到流,因为1)我想测试它是否能正常工作(它组合其他流,进行一些API调用等)2)并且它显然是只读类字段,并且我希望它是这样。
在这里,我创建了一个非常简单的repo和test类版本,以及我想要实现的基本愿景。

import junit.framework.Assert.assertEquals
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
import org.junit.Test

class Repo(dispatcher: CoroutineDispatcher) {

    val flow1 = MutableStateFlow(0)
    val flow2 =  MutableStateFlow(1)

    val sharedFlow = flow1.flatMapLatest { zero ->
        flow2.map { one -> zero to one }
    }.transformLatest { (zero, one) ->
        emit(zero + one)
    }.shareIn(CoroutineScope(dispatcher), SharingStarted.Eagerly, 1)
}

class TestClass {

    @Test
    fun `checking the right state for the shared flow in repo`() = runTest {
        val repo = Repo(testDispatcher)

        launch {
            val state = repo.sharedFlow.firstOrNull()
            assertEquals(state, 1) // 0 + 1
        }.join()
    }
}

我做错了什么?提前感谢你的帮助!

wwwo4jvm

wwwo4jvm1#

好了,我已经弄明白了,最有趣也是最尴尬的是我的例子运行得很好,但是真实的的实现却不行。
这个问题是关于@RelaxedMockK的,它吞下了一个异常,这个异常是我的一个流没有被正确地模拟。因为这个原因,协程没有完成,导致了一个超时异常,而不是一个真正的吞下异常(这就是为什么我认为我可能遇到了调度程序的问题)。因此,如果您使用测试调度程序,请将其提供给您的repo,当它不是一个单元结果函数时,正确地模拟所有内容,而不依赖于宽松的模拟,并等待流接收到第一个数据,然后所有内容都应该正常工作。

相关问题