Recibo el Method myLooper in android.os.Looper not mocked cuando trato de probar mi ViewModel en kotlin usando coroutines.
Ahí está el ViewModel
class MainViewModel(private val uiContext: CoroutineContext = Dispatchers.Main) : ViewModel(), CoroutineScope { private val heroesRepository: HeroesRepository = heroesRepositoryModel.instance() val data = MutableLiveData<List<Heroes.Hero>>() private var job: Job = Job() override val coroutineContext: CoroutineContext get() = uiContext + job fun getHeroesFromRepository(page: Int) { launch { try { val response = withContext(Dispatchers.IO) { heroesRepository.getHeroes(page).await() } data.value = response.data.results } catch (e: HttpException) { data.value = null } catch (e: Throwable) { data.value = null } } } override fun onCleared() { super.onCleared() job.cancel() } }Y el Test que hice para este ViewModel
class HeroesDataSourceTest { @Mock lateinit var heroesRepository: HeroesRepository @Mock lateinit var deferred: Deferred<Heroes.DataResult> val hero = Heroes.Hero(1, "superman", "holasuperman", 1, null, null) val results = Arrays.asList(hero) val data = Heroes.Data(results) val dataResult = Heroes.DataResult(data) @Before fun initTest() { MockitoAnnotations.initMocks(this) } @Test fun testLoadInitialSuccess(): Unit = runBlocking { `when`(heroesRepository.getHeroes(0)).thenReturn(deferred) `when`(deferred.await()).thenReturn(dataResult) var liveData: MutableLiveData<List<Heroes.Hero>> val mainViewModel = MainViewModel(Dispatchers.Unconfined) liveData = mainViewModel.data mainViewModel.getHeroesFromRepository(0) delay(10000L) Assert.assertEquals(dataResult, liveData.value) } } Lo depuro y me da error en la línea data.value = response.data.results del ViewModel. Va a la excepción, pero seguro que como los datos están vacíos, assertEquals será falso.
Revisé este hilo: Método myLooper en android.os.Looper no burlado con Coroutines
Y también esta solución: https://android.jlelse.eu/mastering-coroutines-android-unit-tests-8bc0d082bf15
Eso está funcionando pero en kotlin 1.3 kotlinx.coroutines.experimental.android.UI no funciona.
LiveData usa MainLooper internamente. Agregue esta dependencia (o su versión de biblioteca de soporte):
testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
y esta regla:
@get:Rule val instantExecutorRule = InstantTaskExecutorRule()https://developer.android.com/reference/android/arch/core/executor/testing/InstantTaskExecutorRule