Модульный тест с сопрограммами в kotlinMethod myLooper в android.os.Looper не высмеивается ошибка, когда я пытаюсь Модульный тест в kotlin - PullRequest
0 голосов
/ 22 января 2019

Я получаю ошибку Method myLooper in android.os.Looper not mocked, когда пытаюсь протестировать свою ViewModel в kotlin с использованием corountines.

Theres является 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()
    }
}

И тест, который я сделал для этой 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)
    }

}

Я отлаживаю его, и он дает мне ошибку в строке data.value = response.data.results из ViewModel.Это относится к исключению, но наверняка, поскольку данные пусты, assertEquals будет ложным.

Я проверил эту тему: Метод myLooper в android.os.Looper не покушается на сопрограммы

А также это решение: https://android.jlelse.eu/mastering-coroutines-android-unit-tests-8bc0d082bf15

Это работает, но в kotlin 1.3 kotlinx.coroutines.experimental.android.UI не работает.

1 Ответ

0 голосов
/ 22 января 2019

LiveData использует MainLooper внутри. Добавьте эту зависимость (или ее версию библиотеки поддержки):

testImplementation "androidx.arch.core:core-testing:$lifecycle_version"

и это правило:

@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()

https://developer.android.com/reference/android/arch/core/executor/testing/InstantTaskExecutorRule

...