~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain-android

1 collaborator
0
1
main
34 lines · 1.2 KB Raw History
package social.grain.support

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.rules.TestWatcher
import org.junit.runner.Description

/**
 * Runs `viewModelScope` work off the test thread.
 *
 * Robolectric runs the test body *on* the main thread, so a view model's
 * coroutines and the assertions waiting on them would be the same thread — and
 * anything that blocks waiting for state would deadlock against the work that
 * produces it. `Unconfined` sidesteps that without a virtual clock: each
 * coroutine simply carries on wherever its last suspension resumed it, which
 * for these view models is the IO thread the request came back on.
 *
 * That leaves the tests waiting in real time, which is the point — the stub
 * server answers through OkHttp's own dispatcher, and no test scheduler
 * controls that.
 */
@OptIn(ExperimentalCoroutinesApi::class)
class MainDispatcherRule : TestWatcher() {

    override fun starting(description: Description) {
        Dispatchers.setMain(Dispatchers.Unconfined)
    }

    override fun finished(description: Description) {
        Dispatchers.resetMain()
    }
}