Simulacro de llamadas perdidas dentro de cada bloque { … }

3 minutos de lectura

Avatar de usuario de Budius
Budius

Estoy atascado tratando de burlarme de algunas cosas con mockk:

Tengo la siguiente configuración en gradle

root:
  |-- App (just a sample app for the SDK)
  |-- SDK (SDK we develop) << apply plugin: 'com.android.library'
       |-- SDKimpl.kt
  |-- Foo (wrapper around a .jar library) << apply plugin: 'com.android.library'
       |-- Foo.kt

Así que estoy escribiendo un androidTest para el SDK y tratando de burlarse Foo.kt. No hay nada inusual en la clase Foo, solo directo class Foo(private val someParams) {

entonces usando androidTestImplementation "io.mockk:mockk-android:1.8.13" el simulacro dice:

val mock: Foo = mockk()
// val mock: Foo = mockkClass(Foo::class) // also tried this
every { mock.getData() } returns listOf("1", "2", "3")

Siempre recibo el siguiente bloqueo:

io.mockk.MockKException: Missing calls inside every { ... } block.
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:42)

También intenté solo para recopilar información:

  • ejecutándose dentro de la carpeta de prueba de JVM. Se burla sin problemas, pero no puedo ejecutar mi prueba como JVM
  • correr androidTest adentro Foo módulo. Tengo el mismo accidente
  • usando mockkClass(Foo::class). Tengo un accidente
  • usando anotación @MockK y MockKAnnotations.init(this). Tuve un accidente.
  • agregado Log.d antes every { linea y adentro getData() método y parece que se llama al método real real de la clase durante la configuración simulada. Eso me parece súper raro.

¿Alguna idea de lo que está yendo mal aquí?

editar:

según lo solicitado, código completo. Actualmente estoy trabajando en un proyecto aislado para tratar de aislar el error, por lo que Foo es solo:

class Foo {

    fun getData(): String {
        Log.d(TAG, "invoked foo.getData()")
        return "trolololo"
    }

}

y luego tengo FootTest en androidTest:

class FooTest {

    @Test
    fun mock_foo() {
        val foo = mockk<Foo>()
        every { foo.getData() } returns "zero"
        assertEquals("zero", foo.getData())
    }

}

Parece ser un problema abierto de Mockk: https://github.com/mockk/mockk/issues/182

2 posibles soluciones rápidas (elegir uno):

  1. Ejecutar las Pruebas Instrumentadas en un emulador >= Android-P
  2. Colocar Foo clase como abierta (y los métodos que desea simular también)

Trate de comprobar el guía oficial y ver lo que falta.

En mi caso, traté de simular una extensión en Kotlin pero perdí la mockkStatic

fun Date.asMyTime() : DateTime = DateTime(this, DateTimeZone.getDefault())

mockkStatic("packageName.FileNameKt") // This is what I was missing
every {
    DateTime().asMyTime()
} returns mock(DateTime::class.java)

  • Gracias por mockkStatic("packageName.FileNameKt") cuando el método de extensión de prueba! Querías decir mockkno mock en la ultima linea?

    – CoolMind

    31 de marzo de 2022 a las 23:04

  • En lugar de mockkStatic("packageName.FileNameKt") puedes escribir: mockkStatic(FileName::class.java.name + "Kt").

    – CoolMind

    1 abr 2022 a las 14:40

En mi caso me olvidé de spyk la clase que estaba aplicando every {...} a. 😳

val presenter = spyk(MyPresenter())

every { view.myFun(any()) } returns Unit

  • ¿Podemos agregar any() a spyk

    – Akshay Hazari

    23 de diciembre de 2021 a las 7:13

  • @AkshayHazari spyk se utiliza para agregar capacidades de simulación y verificación a objetos “reales”. Cualquier cosa que se pueda hacer con mockkse puede hacer en spyk‘d objetos, tales como every{}, verify{} etc.

    – Tomás

    28 de diciembre de 2021 a las 22:33

En mi caso, traté de burlarme usando la función de burla () en lugar de burlarmek() (doble k)

En mi caso, me he perdido

@Before
fun setUp() {
    MockKAnnotations.init(this)
}

Asegúrate de que el objeto sea realmente un simulacro, no el objeto real.

Por ejemplo:

- Sdk sdk = Sdk()
+ Sdk sdk = mockk()
  every { sdk.crypto } returns mockk()

avatar de usuario de tonisives
tonificantes

Mi problema fue que usé una clase Java sin captadores.

public class KeyStorePasswordPair {
    public KeyStore keyStore;
    public String keyPassword;

    public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
        this.keyStore = keyStore;
        this.keyPassword = keyPassword;
    }
}

Necesitaba agregar captadores para las variables para hacer que la burla funcionara:

public class KeyStorePasswordPair {
    public KeyStore getKeyStore() {
        return keyStore;
    }

    public String getKeyPassword() {
        return keyPassword;
    }

    private KeyStore keyStore;
    private String keyPassword;

    public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
        this.keyStore = keyStore;
        this.keyPassword = keyPassword;
    }
}

¿Ha sido útil esta solución?