使用kotlin协同程序时,如何对调用暂停函数的函数进行单元测试?

时间:2018-01-05 18:03:47

标签: unit-testing kotlin coroutine kotlin-coroutines

我有一个这样的课程

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内的所有内容都完成。如果我直接在suspendFun()内测试runBlocking,它会按预期工作,但我希望能够一起测试someFun()

有关如何使用同步和异步代码测试函数的任何线索?

1 个答案:

答案 0 :(得分:11)

修复异步

执行后,someFun()只会“触发并忘记”async结果。因此,runBlocking在该测试中没有任何区别。

如果可能,请someFun()返回async的{​​{1}},然后在Deferred中,点击runBlocking

await

然后测试:

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

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

替代方案:使用启动

也可以避免runBlocking { SomeClass().someFun().await() } 支持使用async函数和suspend - 创建的协程:

launch

测试使用suspend fun someFun() { // ... Some synchronous code suspendFun() } private suspend fun suspendFun() { delay(1000) println("executed") // ... other code } ,外部launch隐式等待其完成:

runBlocking