Android Tests – Cannot invoke observeForever on a background thread

Ao realizar um teste utilizando coroutine me deparei com esse problema ao tentar observar um LiveData

Cannot invoke observeForever on a background thread

Para contextualizar o problema, eu estava utilizando um dao do Room com uma suspend function para me retornar um LiveData, exemplo:

@Test
fun myTest() = runBlocking {
    val liveData = dao.selectAll()
    val value = getValue(liveData)
    //asserts
}

/**
 * Helper method for testing LiveData objects, from
 * https://github.com/googlesamples/android-architecture-components.
 *
 * Get the value from a LiveData object. We're waiting for LiveData to emit, for 2 seconds.
 * Once we got a notification via onChanged, we stop observing.
 */
@Throws(InterruptedException::class)
fun <T> getValue(liveData: LiveData<T>): T {
    val data = arrayOfNulls<Any>(1)
    val latch = CountDownLatch(1)
    liveData.observeForever { o ->
        data[0] = o
        latch.countDown()
    }
    latch.await(2, TimeUnit.SECONDS)

    @Suppress("UNCHECKED_CAST")
    return data[0] as T
}

O problema é a execução do observer fora da thread da interface, para solucionar esse problema nos seus testes temos que adicionar ao AndroidJUnit4 uma Rule, para fazer isso basta adicionar a seguinte váriavel na sua classe de teste:

@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()

Você precisa adicionar a seguinte dependência para instanciar um InstantTaskExecutorRule

androidTestImplementation "androidx.arch.core:core-testing:2.0.0"

Essa solução foi encontrada no projeto Sunflower de exemplo da nova arquitetura do android, segue o link do arquivo:

https://github.com/android/sunflower/blob/master/app/src/androidTest/java/com/google/samples/apps/sunflower/data/GardenPlantingDaoTest.kt

Help DEV – Analista desenvolvedor Java / Android https://helpdev.com.br/zarelli

Android Tests – Cannot invoke observeForever on a background thread

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Rolar para o topo