Skip to content

Test helper to use Dispatchers.Main without framework dependencies on JVM #568

@objcode

Description

@objcode

Report version: coroutines 0.26.

In the current implementation of HandlerDispatcher it is not possible to run code that uses Dispatchers.Main in pure-Kotlin tests.

Minimal example:

// MyViewModel.kt
class MyViewModel: ViewModel() {
  val parentJob = Job()
  val uiScope = CoroutineScope(Dispatchers.Main + parentJob)
}
// MyViewModelTest.kt which runs as a unit test without the Android framework
class MyViewModelTest {
   @Test
   fun aTest() {
      val subject = MyViewModel()
   }
}

This leads to a not mocked error.

Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
	at android.os.Looper.getMainLooper(Looper.java)
	at kotlinx.coroutines.experimental.android.HandlerDispatcherKt.<clinit>(HandlerDispatcher.kt:43)

A typical testing solution on Android is to replace the main looper with an immediate executor in test contexts. For example see InstantTaskExecutorRule from Room.

Taking a look at HandlerDispatcher, it appears it's not possible to avoid the call to Looper.getMainLooper as it's used to assign mainHandler, and HandlerDispatcher is listed as a sealed class so the only option to get past this import error in the current implementation is to add indirection to references to Dispatcher.Main.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions