问题
Using this manual to test Coroutines using runBlockingTest
.
I encountered some issues.
If the coroutine created by launch or async calls delay then the runBlockingTest will not auto-progress time right away. This allows tests to observe the interaction of multiple coroutines with different delays.
@Test
fun testFooWithLaunchAndDelay() = runBlockingTest {
foo()
// the coroutine launched by foo has not completed here, it is suspended waiting for delay(1_000)
advanceTimeBy(1_000) // progress time, this will cause the delay to resume
// the coroutine launched by foo has completed here
// ...
}
suspend fun CoroutineScope.foo() {
launch {
println(1) // executes eagerly when foo() is called due to runBlockingTest
delay(1_000) // suspends until time is advanced by at least 1_000
println(2) // executes after advanceTimeBy(1_000)
}
}
Even if i comment out advanceTimeBy(1_000)
time clock progress instantly. Advancing less than delay time not working either.
Time control can be used to test timeout code. To do so, ensure that the function under test is suspended inside a withTimeout block and advance time until the timeout is triggered.
@Test(expected = TimeoutCancellationException::class)
fun testFooWithTimeout() = runBlockingTest {
val uncompleted = CompletableDeferred<Foo>() // this Deferred<Foo> will never complete
foo(uncompleted)
advanceTimeBy(1_000) // advance time, which will cause the timeout to throw an exception
// ...
}
fun CoroutineScope.foo(resultDeferred: Deferred<Foo>) {
launch {
withTimeout(1_000) {
resultDeferred.await() // await() will suspend forever waiting for uncompleted
// ...
}
}
}
This test does not throw TimeoutCancellationException
and fails.
来源:https://stackoverflow.com/questions/61725412/testing-coroutines-runblockingtest-time