问题
I have a class like this
class SomeClass {
    fun someFun() {
        // ... Some synchronous code
        async {
            suspendfun() 
        }
    }
    private suspend fun suspendFun() {
         dependency.otherFun().await()
         // ... other code
    }
}
I want to unit test someFun() so I wrote a unit test that looks like this:
@Test
fun testSomeFun() {
    runBlocking {
        someClass.someFun()
    }
    // ... verifies & asserts
}
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?
回答1:
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.
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()
    }
}
Then the test:
runBlocking {
    SomeClass().someFun().await()
}
This question/answer is a good resource for further information.
alternative: use launch
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
}
The test uses launch and the outer runBlocking implicitly waits for its completion:
val myScope = GlobalScope
runBlocking {
    myScope.launch {
        SomeClass().someFun()
    }
}
来源:https://stackoverflow.com/questions/48118986/when-using-kotlin-coroutines-how-do-i-unit-test-a-function-that-calls-a-suspend