Saltar al contenido

La prueba unitaria de rutina de Kotlin falla con “El módulo con el despachador principal no se pudo inicializar”

Solución:

Al ejecutar pruebas, por ejemplo, para ViewModel que inician corrutinas, es más probable que caiga en la siguiente excepción

java.lang.IllegalStateException: El módulo con el despachador principal no se pudo inicializar. Para las pruebas, se puede utilizar Dispatchers.setMain del módulo kotlinx-coroutines-test

La razón detrás de esto es la falta de Looper.getMainLooper() en el entorno de prueba que está presente en una aplicación real. Para solucionar este problema, debe cambiar el despachador principal con TestCoroutineDispatcher

Asegúrese de tener una dependencia de prueba de rutina en su archivo Gradle

“org.jetbrains.kotlinx: kotlinx-coroutines-test: $ coroutine_version”

SOLUCION 1 – No escalable

Defina lo siguiente en su clase de prueba -> Anote su clase con @ExperimentalCoroutinesApi

val dispatcher = TestCoroutineDispatcher()

@Before
fun setup() {
    Dispatchers.setMain(dispatcher)
}

@After
fun tearDown() {
    Dispatchers.resetMain()
}

Nota: también puede pasar Dispatchers.Main como dependencia del constructor para sus repositorios como CoroutineDispatcher en caso de que tenga uno. Se recomienda no codificar sus despachadores en repositorios / modelos de vista, etc. MIRE ESTO POR FAVOREEEEEEE

Por qué no escalable: deberá copiar y pegar el mismo código en cada clase de prueba

SOLUCION 2 – escalable [Use This – It is used by Google]

En esta solución, crea la regla personalizada. Agregue una clase de utilidad en su paquete de prueba

@ExperimentalCoroutinesApi
class MainCoroutineRule(
    private val dispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
) : TestWatcher(), TestCoroutineScope by TestCoroutineScope(dispatcher) {
    override fun starting(description: Description?) {
        super.starting(description)
        Dispatchers.setMain(dispatcher)
    }

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

Si desea explicaciones sobre la clase de utilidad anterior, consulte este CÓDIGO-LAB.

En su clase de prueba, simplemente agregue las siguientes líneas y estará listo para comenzar

@get:Rule
val coroutineRule = MainCoroutineRule()

Creo que puedes ver por qué esto es escalable si tienes muchas clases de prueba.

SOLUCIÓN 3 [I hope you don’t reach here]

También puedes usar Dispatchers.Unconfined ENLACE

A coroutine dispatcher that is not confined to any specific thread. It executes the initial continuation of a coroutine in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid stack overflows

Puede agregarlo de la siguiente manera

@Before
fun setup() {
    Dispatchers.setMain(Dispatchers.Unconfined)
}

@After
fun tearDown() {
    Dispatchers.resetMain()
}

Codificación feliz. . . .

No tienes acceso a Dispatchers. Principal en pruebas unitarias

Ver https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/

Dispatchers.Main Delegation parte explica en detalle lo que debe hacer.

ahora puedes agregar esto a tu prueba:

Dispatchers.setMain(Dispatchers.Unconfined)

u otro despachador … es experimental pero obras!

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *