Sujit
10/18/2019, 5:11 PMModule with the Main dispatcher had failed to initialize. For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used
. I do have the following in my unit tests:
@ObsoleteCoroutinesApi
private lateinit var mainThreadSurrogate: ExecutorCoroutineDispatcher
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
@Before
fun before() {
mainThreadSurrogate = newSingleThreadContext("UI thread")
Dispatchers.setMain(mainThreadSurrogate)
}
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
@After
fun tearDown() {
Dispatchers.resetMain() // reset main dispatcher to the original Main dispatcher
mainThreadSurrogate.close()
}
This only happens on one of many unit tests in the same class, which is in this place: https://github.com/UrbanCompass/Snail-Kotlin/blob/master/snail-kotlin/src/test/java/com/compass/snail/ObservableTests.kt#L221
I'm making this into a kotlin multiplatform project, and running unit tests through the androidTest
. Any pointers on this please?zak.taccardi
10/18/2019, 5:12 PMzak.taccardi
10/18/2019, 5:12 PMCoroutineScope
zak.taccardi
10/18/2019, 5:13 PMrunBlocking { }
or runBlockingTest { }
for unit testsSujit
10/18/2019, 5:13 PMobservable.debounce(Dispatchers.Default, delayMs = delayMs).subscribe(Dispatchers.Default, next = {
received.add(it)
})
Sujit
10/18/2019, 5:14 PMDispatchers.Main
beforezak.taccardi
10/18/2019, 5:14 PMlouiscad
10/18/2019, 5:14 PM@Before
annotated function.zak.taccardi
10/18/2019, 5:14 PMSujit
10/18/2019, 5:16 PMDispatchers
reference initialized in a different class, that gets injected to the class I'm testing. Is that not the way to do CoroutinesSujit
10/18/2019, 5:27 PM@Before
annotation here. Here's what I've in setup:
private lateinit var subject: Observable<String>
private lateinit var strings: MutableList<String>
private var error: Throwable? = null
private var done: Boolean? = null
@ObsoleteCoroutinesApi
private lateinit var mainThreadSurrogate: ExecutorCoroutineDispatcher
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
@Before
fun before() {
runBlockingTest {
mainThreadSurrogate = newSingleThreadContext("UI thread")
Dispatchers.setMain(mainThreadSurrogate)
subject = Observable()
strings = mutableListOf()
error = null
done = null
subject.subscribe(Dispatchers.Unconfined,
next = { strings.add(it) },
error = { error = it },
done = { done = true }
)
}
}
Sujit
10/18/2019, 5:28 PMrunBlocking{}
scope, that throws out the same error. Sometimes, the test case, pass, but that error message of using setMain
still shows up in the logSujit
10/18/2019, 6:26 PMTestCoroutineDispatcher()
instead of newSingleThreadContext
simple smilezak.taccardi
10/18/2019, 6:27 PMSujit
10/18/2019, 6:28 PMzak.taccardi
10/18/2019, 6:29 PMinterface AppDispatchers {
val main: CoroutineContext get() = Dispatchers.Main
val default: CoroutineContext get() = Dispatchers.Default
val io: CoroutineContext get() = <http://Dispatchers.IO|Dispatchers.IO>
}
This allows for easy testingSujit
10/18/2019, 6:30 PMzak.taccardi
10/18/2019, 6:32 PMEspressoDispatchers()
fun EspressoDispatchers() : AppDispatchers = object : AppDispatchers {
override val default = AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
override val io = AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
}
zak.taccardi
10/18/2019, 6:32 PMCoroutineScope