【问题标题】:When using kotlin coroutines, how do I unit test a function that calls a suspend function?使用 kotlin 协程时,如何对调用挂起函数的函数进行单元测试?
【发布时间】:2018-06-15 14:00:36
【问题描述】:

我有这样的课

class SomeClass {
    fun someFun() {
        // ... Some synchronous code
        async {
            suspendfun() 
        }
    }

    private suspend fun suspendFun() {
         dependency.otherFun().await()
         // ... other code
    }
}

我想对someFun() 进行单元测试,所以我编写了一个如下所示的单元测试:

@Test
fun testSomeFun() {
    runBlocking {
        someClass.someFun()
    }

    // ... verifies & asserts
}

但这似乎不起作用,因为在 runBlocking 中的所有内容完成之前,runBlocking 实际上不会阻止执行。如果我直接在runBlocking 内部测试suspendFun(),它会按预期工作,但我希望能够一起测试someFun()

知道如何使用同步代码和异步代码测试函数吗?

【问题讨论】:

    标签: unit-testing kotlin coroutine kotlin-coroutines


    【解决方案1】:

    修复异步

    在实施时,您的 someFun() 只会“触发并忘记”async 结果。因此,runBlocking 对该测试没有任何影响。

    如果可能,让someFun() 返回asyncDeferred,然后在runBlocking 中调用await

    fun someFun(): Deferred<Unit> {
        // ... Some synchronous code
        return async {
            suspendFun()
        }
    }
    

    然后测试:

    runBlocking {
        SomeClass().someFun().await()
    }
    

    question/answer 是获取更多信息的好资源。

    替代方案:使用启动

    也可以避免使用async,而使用suspend 函数和launch-创建的协程:

    suspend fun someFun() {
        // ... Some synchronous code
        suspendFun()
    }
    
    private suspend fun suspendFun() {
        delay(1000)
        println("executed")
        // ... other code
    }
    

    测试使用launch,外部runBlocking隐式等待其完成:

    val myScope = GlobalScope
    runBlocking {
        myScope.launch {
            SomeClass().someFun()
        }
    }
    

    【讨论】:

    • 这是否意味着如果您不调用.await(),异步块将不会传播任何异常?
    • 如果你忽略它的返回值,你不应该使用async。您应该改用launch,以便在恢复线程中抛出未处理的异常。
    • @MarkoTopolnik 我明白了,当我应该使用启动时,我误用了异步。
    • 为什么是runBlocking { launch { ... }.join() }?你不能用runBlocking { ... }吗?
    • @msrd0 你是对的,但情况并非总是如此。我更新了代码
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 2019-09-09
    • 2021-10-23
    • 2019-05-30
    • 2018-06-13
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    相关资源
    最近更新 更多