Mockito: Intentar espiar el método es llamar al método original
Estoy usando Mockito 1.9.0. Quiero burlarme del comportamiento de un único método de una clase en una prueba JUnit, así que tengo
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
El problema es que, en la segunda línea, myClassSpy.method1()
en realidad se llama, lo que genera una excepción. La única razón por la que estoy usando simulacros es para que más adelante, cada vez que myClassSpy.method1()
se llame, no se llame al método real y myResults
se devuelva el objeto.
MyClass
es una interfaz y myInstance
es una implementación de eso, si eso importa.
¿Qué debo hacer para corregir este comportamiento de espionaje?
Permítanme citar la documentación oficial :
¡Importante truco para espiar objetos reales!
A veces es imposible utilizar when(Object) para detectar espías. Ejemplo:
List list = new LinkedList(); List spy = spy(list); // Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo"); // You have to use doReturn() for stubbing doReturn("foo").when(spy).get(0);
En tu caso es algo como:
doReturn(resultsIWant).when(myClassSpy).method1();
En mi caso, usando Mockito 2.0, tuve que cambiar todos los any()
parámetros nullable()
para poder bloquear la llamada real.
Mi caso fue diferente a la respuesta aceptada. Estaba intentando burlarme de un método privado de paquete para una instancia que no se encontraba en ese paquete.
package common;
public class Animal {
void packageProtected();
}
package instances;
class Dog extends Animal { }
y las clases de prueba
package common;
public abstract class AnimalTest<T extends Animal> {
@Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
@Test
public void myTest(){}
}
La compilación es correcta, pero cuando intenta configurar la prueba, invoca el método real.
Declarar el método protegido o público soluciona el problema, aunque no es una solución limpia.