У меня есть следующая тестовая функция:
@Test
fun `registerUser verify that loading was emitted`() {
runBlocking {
var emission = 0
val viewModel = createSubject()
viewModel.loading.observeForever {
if (emission == 0) {
assertNotNull(it)
assertFalse(it!!) //MARK #1
emission++
}
}
async { viewModel.registerCommand.registerUser("asd") }.await()
assertNotNull(viewModel.loading.value)
}
}
Я завернул registerUser
вызов с async
и await
в соответствии с this .
Внутри registerUser
:
fun registerUser(username: String) {
launch {...
withContext(ConfigurableDispatchers.IO) {...}
...
}
}
Принимая во внимание, что класс, имеющий эту функцию в качестве члена, наследует CoroutineScope
и переопределяет coroutineContext
с помощью ConfigurableDispatchers.Main + job
, тогда как тестирование durint (в @BeforeClass
-аннотированном методе) ConfigurableDispatchers.Main
указан с
object : MainCoroutineDispatcher() {
@ExperimentalCoroutinesApi
override val immediate: MainCoroutineDispatcher
get() = throw UnsupportedOperationException()
override fun dispatch(context: CoroutineContext, block: Runnable) {
block.run()
}
}
Кроме того, ConfigurableDispatchers.IO
указан с Dispatchers.Unconfined
.
Проблема заключается в том, что исключение подтверждения, выданное из MARK #1
, просто печатается вконсоль, а затем просто проглотил.Тесты пройдены ... Как я вижу и как я отлаживал - все это тело метода выполняется в одном потоке, поэтому, если исключение перехватывается по умолчанию UncaughtExceptionHandler
, то, как я понимаю, ** testдолжен потерпеть неудачу **.Что также интересно, когда я обертываю MARK #1
(ошибочную строку) блоком try catch
, тогда как я ловлю Exception
- в обработчике ничего не падает ...
Почему?