vrg*_*grg 2 kotlin kotlin-coroutines kotlin-flow kotest kotlin-coroutines-flow
我正在尝试使用 Flows 测试 Kotlin 实现。我使用 Kotest 进行测试。此代码有效:
视图模型:
val detectedFlow = flow<String> {
emit("123")
delay(10L)
emit("123")
}
Run Code Online (Sandbox Code Playgroud)
测试:
class ScanViewModelTest : StringSpec({
"when the flow contains values they are emitted" {
val detectedString = "123"
val vm = ScanViewModel()
launch {
vm.detectedFlow.collect {
it shouldBe detectedString
}
}
}
})
Run Code Online (Sandbox Code Playgroud)
但是,在真正的 ViewModel 中我需要向流添加值,所以我使用ConflatedBroadcastChannel如下:
private val _detectedValues = ConflatedBroadcastChannel<String>()
val detectedFlow = _detectedValues.asFlow()
suspend fun sendDetectedValue(detectedString: String) {
_detectedValues.send(detectedString)
}
Run Code Online (Sandbox Code Playgroud)
然后在测试中我尝试:
"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 }
}
}
Run Code Online (Sandbox Code Playgroud)
测试只是挂起,永远不会完成。我尝试了各种各样的事情:launch或者runBlockingTest不是runBlocking,将发送和收集放在相同或单独的协程中,offer而不是send......似乎没有什么可以解决它。我究竟做错了什么?
更新:如果我手动创建流它的工作原理:
private val _detectedValues = ConflatedBroadcastChannel<String>()
val detectedFlow = flow {
this.emit(_detectedValues.openSubscription().receive())
}
Run Code Online (Sandbox Code Playgroud)
那么,这是asFlow()方法上的错误吗?
小智 8
问题是您在测试中使用的collect函数是一个挂起函数,它将挂起执行直到Flow完成。
在第一个例子中,你detectedFlow是有限的。它只会发出两个值并完成。在您的问题更新中,您还将创建一个有限流,它将发出一个值并完成。这就是您的测试有效的原因。
但是,在第二个(现实生活中的)示例中,流是从ConflatedBroadcastChannel 从未关闭的a 创建的。因此该collect函数永远挂起执行。为了使测试工作而不会永远阻塞线程,您还需要使流程有限。我通常first()为此使用运算符。另一种选择是close对ConflatedBroadcastChannel,但是这通常意味着修改您的代码只是因为测试是不是一个好的做法。
这是您的测试与first()操作员一起工作的方式
"when the flow contains values they are emitted" {
val detectedString = "123"
val vm = ScanViewModel()
runBlocking {
vm.sendDetectedValue(detectedString)
}
runBlocking {
vm.detectedFlow.first() shouldBe detectedString
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1558 次 |
| 最近记录: |