このようなクラスがあります
_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()
をすべて一緒にテストできるようにしたいと思います。
同期コードと非同期コードの両方で関数をテストする方法の手がかりはありますか?
実装されているように、あなたのsomeFun()
はasync
の結果を「発射して忘れる」だけです。その結果、runBlocking
はそのテストで違いを生じません。
可能であれば、someFun()
がasync
のDeferred
を返し、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()
}
}