How do you unit test coroutines that use `withCont...
# android
m
How do you unit test coroutines that use
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
, is there a way to replace
<http://Dispatchers.IO|Dispatchers.IO>
to use the main thread in unit tests? Or do I have to pass a dispatcher with DI to replace in tests?
m
I use a class which provide the context; and override it for the Unit tests. So, the class is
Copy code
open class CoroutineContextProvider {
    open val Main: CoroutineContext by lazy { Dispatchers.Main }
    open val IO: CoroutineContext by lazy { Dispatchers.Default }
}
You can use it like this :
GlobalScope.launch(coroutineContextProvider.Main) { (...) }
And for the Unit tests, you can override this class like this :
Copy code
object MockCoroutineContextProvider : CoroutineContextProvider() {
    override val Main: CoroutineContext = Dispatchers.Unconfined
    override val IO: CoroutineContext = Dispatchers.Unconfined
}
g
did you try with
runBlocking{}
? If I understand it correctly, most of the time you don't even have to worry about the different context down the stream, because it's all suspended and will be synchronous at the end... Other than that yes, injecting via DI seems like a straight forward solution.
👍 1
m
I was using
runBlocking{}
but it didn't work, now that you reassured me that it should I found that the error I was getting was actually not because of coroutines and
runBlocking{}
does actually solve this problem... Thanks.
😉 2
d
DI is the best solution, but you have to ensure you pass the correct scope/contexts down the whole chain.
m
Yeah I will go the DI route if
runBlocking
isn't sufficient in the future.