我想测试一个函数,在其中我使用callbackFlow构建器的作用域。假设我在流生成器中有一个函数,如下所示:
fun items(): Flow<Items> = callbackFlow {
getItems(this) {
trySend(it)
}
awaitClose()
}在getItems函数中,我从websockets接收数据。ProducerScope的作用域用于launch、一个具有延迟的新的协同线并执行一些操作,或者在发生错误时用于close该范围。因此,它可能称为scope.launch { }或scope.close()。
例如,这样做可以做到以下几点:
fun getItems(scope: ProducerScope<Items>, callback: (Items) -> Unit) {
if (something) {
scope.launch { ... }
}
if (somethingElse) {
...
scope.close(error)
}
...
callback(items)
}回调流的块使用ProducerScope,CoroutineScope和SendChannel的扩展,我尝试使用莫克来模拟它
val scope: ProducerScope<Items> = mockk()不幸的是,我的结局是:
kotlin.coroutines.CoroutineContext$Element$Subclass6类不能转换为kotlin.coroutines.ContinuationInterceptor类
我怎么能模仿ProducerScope
当getItems既可以是CoroutineScope又可以是SendChannel时,我如何对scope进行单元测试?
提前谢谢。
发布于 2022-03-18 13:48:04
经过多次尝试,我不能轻易地做到这一点,而不期望有奇怪的行为。因此,我重构了我的函数,分别使用了Channel和CoroutineScope。多亏了扩展,我可以从流构建器中创建一个新的作用域。这现在是可测试的!
因此,流生成器变成:
fun items(): Flow<Items> = callbackFlow {
val channel = this.channel
val scope = this.plus(this.coroutineContext)
getItems(channel, scope) {
...
}
...
}我的函数仍然同时使用这两种方法,但分别获取它们:
fun getItems(
channel: SendChannel<Items>,
scope: CoroutineScope,
callback: (Items) -> Unit
) {
if (something) {
scope.launch { ... } // <-- use scope
}
if (somethingElse) {
...
channel.close(error) // <-- use channel
}
...
callback(items)
}然后,我现在可以使用Channel进行测试,其需求与callbackFlow中的需求以及runTest中的作用域相同。
@Test
fun `get items and succeed`() = runTest {
val channel = Channel<Any>(Channel.BUFFERED, BufferOverflow.SUSPEND)
...
service.getItems(channel, this@runTest, callback)
...
}https://stackoverflow.com/questions/71465589
复制相似问题