Closed
Description
@julioyg found an interesting bug(?) regarding the TestCoroutineDispatcher.
The fact that runBlockingTest
uses async
to run the test body (TestBuilders.runBlockingTest#L49), by the time it tries to throw an exception, the test has already completed.
Problems:
-
Silent exceptions
If the coroutine inside a function throws an exception, the test passes and the exception is thrown silently to the console. -
Tests that expect an exception to be thrown
Consider the following scenario. Since we're running this in a blocking way, the expectation is that the exception is thrown, but it is not.
class MyViewModel(): ViewModel() {
fun throwException() {
viewModelScope.launch {
throw Exception("Not found")
}
}
}
class MyViewModelTest {
@get:Rule
var coroutinesTestRule = CoroutinesTestRule()
@Test
fun testExceptionThrown() = coroutinesTestRule.testDispatcher.runBlockingTest {
val assertionThrown = false
try {
val viewModel = MyViewModel()
viewModel.throwException()
} catch(e: Exception) {
assertionThrown = true
}
assertTrue(assertionThrown)
}
}