TestCoroutineDispatcher
See original GitHub issueI have a method with next piece of code
viewModelScope.launch(exceptionHandler) {
val rateList = withContext(Dispatchers.IO) {
buildExchangeRateUseCase.execute(selected)
}
rates.onNext(rateList)
}
and test is
coEvery {
buildExchangeRatesUseCaseMock.execute(selectedRate)
} returns exchangeRates
viewModel = ExchangeRateLifecycleAwareViewModel(buildExchangeRatesUseCaseMock)
assertData(exchangeRates, viewModel.rates)
I have also called Dispatchers.setMain(testDispatcher)
The problem is code inside withContext()
is called asynchronously after assertion happens. A code inside my exceptionHandler
also is called after assertion in case I want to assert exception behavior.
I was able to solve that using runBlocking instead of withContext. However, in documentation it is said runBlocking should not be used from a coroutine
. Although, in coroutines basic guide you gave both these functions to jump between threads (https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html#jumping-between-threads).
Could you please give an idea, how to first execute all the code inside withContext() before assertion is called?
P.S. I have tried runBlockingTest() but it also has no effect
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:7 (2 by maintainers)
DI is the only solution for now.
We have plans to focus on testability in 1.3.1 right after the flow release. It will include stabilization of test dispatcher and (probably) mockable default and IO dispatchers, similar to Main dispatched (
Dispatchers.setMain
in kotlinx-coroutines-test)We thoroughly reworked the test module in https://github.com/Kotlin/kotlinx.coroutines/commit/2e25baeb29274853a1926f6bf7c3be761f306d72, so now it supports multithreading and waiting for external completions. It is still preferable to use DI since the delays in the tasks forked off to other dispatchers are not skipped, but at least it’s now possible to write tests while using third-party code.