问题描述
我有一个像这样的班
class SomeClass {
fun someFun() {
// ... Some synchronous code
async {
suspendfun()
}
}
private suspend fun suspendFun() {
dependency.otherFun().await()
// ... other code
}
}
我想进行单元测试someFun()
,所以我写了一个看起来像这样的单元测试:
I want to unit test someFun()
so I wrote a unit test that looks like this:
@Test
fun testSomeFun() {
runBlocking {
someClass.someFun()
}
// ... verifies & asserts
}
但是这似乎不起作用,因为在完成runBlocking内部的所有操作之前,runBlocking实际上不会阻止执行.如果我直接在runBlocking
内部测试suspendFun()
,它会按预期工作,但是我希望能够一起测试someFun()
.
But this doesn't seem to work because runBlocking doesn't actually block execution until everything inside runBlocking is done. If I test suspendFun()
directly inside runBlocking
it works as expected but I want to be able to test someFun()
all together.
有什么线索可以同时使用同步代码和异步代码测试功能吗?
Any clue how to test a function with both sync and async code?
推荐答案
修复异步
实施后,您的someFun()
只会触发并忘记" async
结果.结果,runBlocking
在该测试中没有任何作用.
Fixing async
As implemented, your someFun()
will just "fire and forget" the async
result. As a result, runBlocking
does not make a difference in that test.
如果可能,请使someFun()
返回async
的Deferred
,然后在runBlocking
中调用await
.
If possible, make someFun()
return async
's Deferred
and then, in runBlocking
, call await
on it.
fun someFun(): Deferred<Unit> {
// ... Some synchronous code
return async {
suspendFun()
}
}
然后进行测试:
runBlocking {
SomeClass().someFun().await()
}
此问题/答案是获取更多信息的好资源.
This question/answer is a good resource for further information.
也可以避免使用suspend
函数和launch
创建的协程,而使用suspend
:
It's also possible to avoid async
in favor of using suspend
functions and a launch
-created coroutine:
suspend fun someFun() {
// ... Some synchronous code
suspendFun()
}
private suspend fun suspendFun() {
delay(1000)
println("executed")
// ... other code
}
测试使用launch
,而外部runBlocking
隐式等待其完成:
The test uses launch
and the outer runBlocking
implicitly waits for its completion:
val myScope = GlobalScope
runBlocking {
myScope.launch {
SomeClass().someFun()
}
}
这篇关于使用Kotlin协程时,如何对调用暂停函数的函数进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!