Mockito: Intentar espiar el método es llamar al método original

Resuelto Dave asked hace 12 años • 11 respuestas

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 myResultsse devuelva el objeto.

MyClasses una interfaz y myInstancees una implementación de eso, si eso importa.

¿Qué debo hacer para corregir este comportamiento de espionaje?

Dave avatar Jul 24 '12 03:07 Dave
Aceptado

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();
Tomasz Nurkiewicz avatar Jul 23 '2012 20:07 Tomasz Nurkiewicz

En mi caso, usando Mockito 2.0, tuve que cambiar todos los any()parámetros nullable()para poder bloquear la llamada real.

ejaenv avatar Mar 29 '2017 20:03 ejaenv

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.

Maragues avatar Aug 02 '2016 10:08 Maragues