Наличие модульного теста, который проверяет результат выборки данных. Но после переключения на использование сопрограмм ошибка модульного теста больше не отображается, как прежде.
В приложении DataRequest.kt, который будет извлекать список данных и отправлять его в liveData, это происходит внутри запуска сопрограммы {}:
Существует исключениеHandler для coroutineScope:
private val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception ->
Log.e(TAG, "!!! exception in coroutineExceptionHandler($exception)")
exception.printStackTrace()
......
}
И используется при запуске задания корневых сопрограмм:
@Throws(Exception::class)
private fun launchCoroutine(block: suspend CoroutineScope.() -> Unit): Job = serviceScope.launch(context = coroutineExceptionHandler, block = block)
Задание сопрограмм начинается с вызова:
launchCoroutine {
doDataFetch()
}
doDataFetch () извлекает данные, и когда список данных готов к обратному вызову, он вызывает onDataFetchedReady()
, который отправляет сообщение в liveData в postDataList(list)
suspend fun onDataFetchedReady() = withContext(Dispatchers.IO) {
...
launch {
postDataList(list)
}
}
И в модульном тесте его наблюдатель liveData получит обновление liveData и вызовет функцию теста verifyExpectedDataSize()
, где он может обнаружить ошибку:
ListRequesterTest.kt
@RunWith(AndroidJUnit4::class)
fun verifyExpectedDataSize(
originalList: List<Data>,
resultList: List<Data>
): Int {
... ...
assertTrue("the data size is wrong", (dataSize > 0 && resultList.size >= dataSize))
... ...
}
В logCat он показывает:
E/DataRequest: !!! exception in coroutineExceptionHandler(java.lang.AssertionError: the data size is wrong)
Suppressed: java.lang.AssertionError: the data size is wrong
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at com.xxx.ListRequesterTest$verifyExpectedDataSize(ListRequesterTest:200)
at com.xxx.ListRequesterTest$LiveDataObserver.onChanged(ListRequesterTest.kt:64)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:113)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:131)
at androidx.lifecycle.LiveData.setValue(LiveData.java:289)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at androidx.lifecycle.LiveData$1.run(LiveData.java:91)
at androidx.arch.core.executor.testing.InstantTaskExecutorRule$1.postToMainThread(InstantTaskExecutorRule.java:43)
at androidx.arch.core.executor.ArchTaskExecutor.postToMainThread(ArchTaskExecutor.java:101)
at androidx.lifecycle.LiveData.postValue(LiveData.java:273)
at androidx.lifecycle.MutableLiveData.postValue(MutableLiveData.java:28)
at com.yyy.DataRequest.postDataList(DataRequest.kt:200)
at com.yyy.DataRequest.access$postDataList(DataRequest.kt:39)
at com.yyy.DataRequest$onDataReady$2$invokeSuspend$$inlined$synchronized$lambda$3.invokeSuspend(DataRequest.kt:508)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
В тесте в IDE он показывает зеленую галочку и не выдает ошибку «Тесты завершены». Но в logCat он показывает, что тест не пройден Suppressed: java.lang.AssertionError: the data size is wrong
Как предотвратить обработчик исключений сопрограмм от проглатывания теста?