Excepción de Mockito: cuando () requiere un argumento que tiene que ser una llamada de método en un simulacro

4 minutos de lectura

avatar de usuario
jsf

Tengo un caso de prueba muy simple que usa el marco Mockito y Spring Test. Cuando lo hago

when(pcUserService.read("1")).thenReturn(pcUser);

Obtengo esta excepción.

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.

    at com.project.cleaner.controller.test.PcUserControllerTest.shouldGetPcUser(PcUserControllerTest.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)

Lo he intentado con diferentes métodos, pero sigo recibiendo este mensaje de error. Estoy usando Spring 3.1.0.RELEASE con Mockito. Por favor, comparte y guíame en la dirección correcta.

  • Tengo el mismo problema, pero estoy usando: @Autowired @ReplaceWithMock(beanName=”logDao”) private LogDao logDaoMock;

    –Marcin Erbel

    23 de diciembre de 2013 a las 9:36


Primero debe crear un MOCK de pcUserService y luego usar ese simulacro.

PcUserService mock = org.mockito.Mockito.mock(PcUserService.class);
when(mock.read("1")).thenReturn(pcUser);

  • Pero no puedo depurar en ese caso. ¿Realmente llama a ese método?

    – eatSleepCode

    10 de junio de 2014 a las 13:13

  • @eatSleepCode: el método REAL PcUserService.read nunca se invoca en este ejemplo. En su lugar, se invoca un Mockito Mock, y este simulacro regresa pcUser

    – Ralph

    10 de junio de 2014 a las 13:43

  • sí, tengo un problema con esto, tengo un servicio, digamos TestService y tiene un metodo testMethod() y código dentro testMethod incluye llamada a otro método de servicio para, por ejemplo. AnotherTestService.getData(). Entonces en mi caso no soy capaz de burlarme AnotherTestService ¿Qué tengo que hacer?

    – eatSleepCode

    11 de junio de 2014 a las 4:52


  • ¿Por qué no puedes reemplazar AnotherTestService con un simulacro?

    – Ralph

    11 de junio de 2014 a las 5:21

  • @eatSleepCode: tal vez debería echar un vistazo a esta respuesta: stackoverflow.com/a/20856647/280244

    – Ralph

    11 de junio de 2014 a las 5:33

En caso de que otros tengan este problema….

También podría darse el caso de que el método que está tratando de simular,pcUserService.readse declara como final método. Por lo que he notado, esto parece causar problemas con Mockito.

  • El diagnostico esta bien, pero cual es la solucion :p

    – amdev

    22 de julio de 2018 a las 7:07

  • @amdev No hagas pcUserService.read final 🙂 No es lo ideal, lo sé, pero no hay mucho que puedas hacer al respecto. Mockito no puede burlarse de un método final. Consulte stackoverflow.com/questions/3793791/final-method-mocking para obtener más detalles y posibles soluciones.

    – djkelly99

    24/07/2018 a las 21:37

  • En realidad, a veces no te burlas de tu propia clase, sino de alguna clase de dependencias externas. Pero está bien, encontré cómo simular el método final con mockito stackoverflow.com/questions/14292863/…

    – amdev

    25 de julio de 2018 a las 7:32

avatar de usuario
CoolMind

Si utiliza Kotlindebes saber que los métodos son final por defecto. así que escribe open fun en vez de fun. Gracias a @djkelly99 por un consejo.

  • Gracias esto funcionó. Pero 1 pregunta. ¿Cómo resolvería este problema sin hacer que el método y la clase sean como open

    – víbora

    2 de octubre de 2019 a las 5:27

  • @viper, gracias! No uso pruebas ahora, pero supongamos que debería usar una versión más nueva de esta biblioteca. si no me equivoco es compatible final métodos. Probablemente puedas intentar crear interfaces o clases abstractas.

    – CoolMind

    2 de octubre de 2019 a las 7:09


  • tengo la última versión de mockito pero sigo teniendo el problema. ¿Cuáles son los inconvenientes de usar un open modificador?

    – víbora

    2 de octubre de 2019 a las 7:12

  • @viper, consulte stackoverflow.com/questions/14292863/…, github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2, github.com/powermock/powermock/wiki/mockito.

    – CoolMind

    2 de octubre de 2019 a las 7:16

  • @viper, significa que los descendientes de tu open la clase puede cambiar un comportamiento de una manera que no esperaba. Los métodos anulados pueden acceder a las colecciones a las que no quería acceder. O incluso cambiar colecciones, objetos. Ver también quora.com/Cuáles-son-todas-las-ventajas-de-la-herencia-en-Java, quora.com/Cuáles-son-las-desventajas-de-la-herencia-en-Java.

    – CoolMind

    2 de octubre de 2019 a las 7:27


Otra solución a este problema podría ser que, en el caso de una clase de prueba que esté utilizando PowerMockRunneres posible que deba agregar la clase de la que se está burlando a la lista, en @PrepareForTest anotación.

Por ejemplo –

@PrepareForTest({ PcUserService.class })

En mi caso se solucionó inyectando @MockBean.

por ej.

@MockBean
StateRepository mockStateRepository;

avatar de usuario
Michael ‘PuszekSE’

Hay otra razón posible para tal error: a veces, IDE prefiere importar estáticamente Mockito.when() desde otro paquete:

import static io.codearte.catchexception.shade.mockito.Mockito.when;

contra

import static org.mockito.Mockito.when; //should normally use this one

La cosa es ‘cuando’ del paquete io.codearte cumple con org.mockito.Mockito.any() en el nivel de compilación, pero falla durante el tiempo de ejecución con exactamente el mismo mensaje de error.

avatar de usuario
Tomás Preis

Tuve el mismo problema, el método que estaba tratando de burlarme era un método final. Quité el modificador y funcionó bien.

¿Ha sido útil esta solución?