我正在尝试使用 Flows 测试 Kotlin 实现。我使用 Kotest 进行测试。此代码有效:
视图模型:
val detectedFlow = flow<String> {
emit("123")
delay(10L)
emit("123")
}
测试:
class ScanViewModelTest : StringSpec({
"when the flow contains values they are emitted" {
val detectedString = "123"
val vm = ScanViewModel()
launch {
vm.detectedFlow.collect {
it shouldBe detectedString
}
}
}
})
但是,在真正的 ViewModel 中我需要向流中添加值,所以我使用ConflatedBroadcastChannel
如下:
private val _detectedValues = ConflatedBroadcastChannel<String>()
val detectedFlow = _detectedValues.asFlow()
suspend fun sendDetectedValue(detectedString: String) {
_detectedValues.send(detectedString)
}
然后在测试中我尝试:
"when the flow contains values they are emitted" {
val detectedString = "123"
val vm = ScanViewModel()
runBlocking {
vm.sendDetectedValue(detectedString)
}
runBlocking {
vm.detectedFlow.collect { it shouldBe detectedString }
}
}
测试只是挂起并且永远不会完成。我尝试了各种各样的事情:launch
或者runBlockingTest
代替runBlocking
,将发送和收集放在相同或单独的协同程序中,offer
而不是send
......似乎没有什么可以解决它。我究竟做错了什么?
更新:如果我手动创建流程,它可以工作:
private val _detectedValues = ConflatedBroadcastChannel<String>()
val detectedFlow = flow {
this.emit(_detectedValues.openSubscription().receive())
}
那么,这是asFlow()
方法中的错误吗?