Kotlin协程:在测试Android Presenter时切换上下文 [英] Kotlin coroutines: Switching context when testing an Android Presenter

查看:375
本文介绍了Kotlin协程:在测试Android Presenter时切换上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在我的Android项目中开始使用kotlin协程,但是我对此有一些疑问.许多人会称它为代码气味.

I've started using kotlin coroutines in my Android project recently, but I have somewhat of a problem with it. Many would call it a code smell.

我使用的是MVP架构,其中协程以这样的方式在我的演示者中启动:

I'm using an MVP architecture where the coroutines are started in my presenter like this:

// WorklistPresenter.kt
...
override fun loadWorklist() {
    ...
    launchAsync { mViewModel.getWorklist() }
    ...

launchAsync函数是通过这种方式实现的(在我的WorkPrePreter类扩展的BasePresenter类中):

The launchAsyncfunction is implemented this way (in my BasePresenter class that my WorklistPresenter class extends):

@Synchronized
protected fun launchAsync(block: suspend CoroutineScope.() -> Unit): Job {
    return launch(UI) { block() }
}

这个问题是我正在使用依赖于Android Framework的UI协程上下文.如果没有遇到ViewRootImpl$CalledFromWrongThreadException,就无法将其更改为其他协程环境.为了能够对此进行单元测试,我创建了BasePresenter的副本,该副本具有launchAsync的不同实现:

The problem with this is that I'm using a UI coroutine context that depends on the Android Framework. I can't change this to another coroutine context without running into ViewRootImpl$CalledFromWrongThreadException. To be able to unit test this I've created a copy of my BasePresenter with a different implementation of launchAsync:

protected fun launchAsync(block: suspend CoroutineScope.() -> Unit): Job {
    runBlocking { block() }
    return mock<Job>()
}

对我来说,这是个问题,因为现在必须在两个地方维护我的BasePresenter.所以我的问题是.如何更改实现以支持简单测试?

To me this is a problem because now my BasePresenter has to be maintained in two places. So my question is. How can I change my implementation to support easy testing?

推荐答案

我建议将launchAsync逻辑提取到一个单独的类中,您可以在测试中简单地模拟它.

I’d recommend to extract the launchAsync logic into a separate class, which you can simply mock in your tests.

class AsyncLauncher{

    @Synchronized
    protected fun execute(block: suspend CoroutineScope.() -> Unit): Job {
        return launch(UI) { block() }
    }

}

它应该是您的活动构造函数的一部分,以使其可替换.

It should be part of your activity constructor in order to make it replaceable.

这篇关于Kotlin协程:在测试Android Presenter时切换上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆