【发布时间】:2020-05-13 10:36:46
【问题描述】:
我正在尝试使用 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() 方法中的错误吗?
【问题讨论】:
-
您是否尝试在其他调度程序上启动,只是为了调试目的?
-
是的,我做到了。没有效果。顺便说一句,我尝试了新发布的 StateFlow/MutableStateFlow 问题仍然存在
标签: kotlin kotlin-flow kotlin-coroutines kotest