Hoy me topé con una situación que no entiendo, posiblemente debido a la falta de conocimiento sobre cómo funcionan internamente mockito y mockito-kotlin.
Dado el siguiente código, desde mi perspectiva de principiante de Kotlin, tengo dos métodos de interfaz bastante similares. Uno devuelve Boolean, una Cadena. Ambas son funciones de suspensión en mi ejemplo, ya que en mi situación del mundo real, mis funciones también lo son.
class ITestInterface { suspend fun returnBoolean(): Boolean { return true } suspend fun returnSomeString() : String { return "String" } } @Test fun demoTest() { val implMock = mock<ITestInterface> { on { runBlocking { returnSomeString() } } doReturn "Hello" on { runBlocking { returnBoolean() } } doReturn false } }
Mi observación es que, cuando ejecuto la prueba, como se muestra arriba, aparece el siguiente mensaje de error
com.nhaarman.mockitokotlin2.MockitoKotlinException: NullPointerException thrown when stubbing. This may be due to two reasons: - The method you're trying to stub threw an NPE: look at the stack trace below; - You're trying to stub a generic method: try `onGeneric` instead. at com.nhaarman.mockitokotlin2.KStubbing.on(KStubbing.kt:72) at com.rewedigital.fulfillment.picking.components.substitute.DemoTest.demoTest(DemoTest.kt:30)
[...]
Los experimentos demostraron que
¿Alguien podría explicar por qué sucede esto? ¿Hasta qué punto tenemos que ver con los genéricos aquí? ¿Y cuál sería la forma correcta de resolver el problema en nuestra aplicación real? ¿Tienes un montón de on {} y algo de onGeneric {} ?
¡Gracias por tu ayuda!
Debe usar el método onBlocking para simular correctamente la función de suspensión
Por favor, intente con el siguiente código:
@Test fun demoTest() { val implMock = mock<ITestInterface> { onBlocking { returnSomeString() } doReturn "Hello" onBlocking { returnBoolean() } doReturn false } runBlocking { // Execute your code here assertThat(implMock.returnSomeString()).isEqualTo("Hello") assertThat(implMock.returnBoolean()).isEqualTo(false) } }