Cant call code with UI context usage in android unit tests. Test throw:
Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked.
Need opportunity to substitute context.
You can try to define a function that returns a context and use it in your code. Then you'll be able to mock it. Will it work for your case?
Currently i use follow solution:
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.EmptyCoroutineContext
import kotlinx.coroutines.experimental.android.UI as mainLooperContext
val UI by lazy { initializationBlock() }
private var initializationBlock: () -> CoroutineContext = { mainLooperContext }
fun stubUiContext() {
initializationBlock = { EmptyCoroutineContext }
}
But perhaps this problem will appear not only for me in the future.
What kind of solution you'd like in kotlinx.coroutines for that?
@milk-machine I think that's not related to coroutines. Just inject context, like you do in Rx Java https://medium.com/@peter.tackage/an-alternative-to-rxandroidplugins-and-rxjavaplugins-scheduler-injection-9831bbc3dfaf
What kind of solution you'd like in kotlinx.coroutines for that?
I think good solution would be in-built mechanism to replace any scheduler (UI in this case) with instant execution scheduler for Unit tests, similar to how RxJava does this with RxAndroidPlugins.
While solution that @dmytrodanylyk mentions works, it creates a lot of additional unnecessary boilerplate code.
I am very much against that. RxJava got it wrong. We already have a mechanism for that: inversion of control.
Closing this issue. We will not providing ability to replace standard contexts in the library.
:eyes: Related article: Unit testing with MutableLiveData
Most helpful comment
I am very much against that. RxJava got it wrong. We already have a mechanism for that: inversion of control.