首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Kotlin流中从ProducerScope构建器中模拟callbackFlow?

如何在Kotlin流中从ProducerScope构建器中模拟callbackFlow?
EN

Stack Overflow用户
提问于 2022-03-14 09:37:11
回答 1查看 390关注 0票数 0

我想测试一个函数,在其中我使用callbackFlow构建器的作用域。假设我在流生成器中有一个函数,如下所示:

代码语言:javascript
复制
fun items(): Flow<Items> = callbackFlow {
    getItems(this) {
        trySend(it)
    }
    awaitClose()
}

getItems函数中,我从websockets接收数据。ProducerScope的作用域用于launch、一个具有延迟的新的协同线并执行一些操作,或者在发生错误时用于close该范围。因此,它可能称为scope.launch { }scope.close()

例如,这样做可以做到以下几点:

代码语言:javascript
复制
fun getItems(scope: ProducerScope<Items>, callback: (Items) -> Unit) {
    if (something) {
        scope.launch { ... }
    }
    if (somethingElse) {
        ...
        scope.close(error)
    }
    ...
    callback(items)
}

回调流的块使用ProducerScopeCoroutineScopeSendChannel的扩展,我尝试使用莫克来模拟它

代码语言:javascript
复制
val scope: ProducerScope<Items> = mockk()

不幸的是,我的结局是:

kotlin.coroutines.CoroutineContext$Element$Subclass6类不能转换为kotlin.coroutines.ContinuationInterceptor类

我怎么能模仿ProducerScope

getItems既可以是CoroutineScope又可以是SendChannel时,我如何对scope进行单元测试?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-18 13:48:04

经过多次尝试,我不能轻易地做到这一点,而不期望有奇怪的行为。因此,我重构了我的函数,分别使用了ChannelCoroutineScope。多亏了扩展,我可以从流构建器中创建一个新的作用域。这现在是可测试的!

因此,流生成器变成:

代码语言:javascript
复制
fun items(): Flow<Items> = callbackFlow {
    val channel = this.channel
    val scope = this.plus(this.coroutineContext)

    getItems(channel, scope) {
        ...
    }
    ...
}

我的函数仍然同时使用这两种方法,但分别获取它们:

代码语言:javascript
复制
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中的作用域相同。

代码语言:javascript
复制
@Test
fun `get items and succeed`() = runTest {
    val channel = Channel<Any>(Channel.BUFFERED, BufferOverflow.SUSPEND)
    ...

    service.getItems(channel, this@runTest, callback)
    ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71465589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档