Estoy usando Mockito 1.9.0. Quiero simular el comportamiento de un solo 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, en myClassSpy.method1()
realidad se llama, lo que resulta en una excepción. La única razón por la que estoy usando simulacros es para que luego, 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?
Respuestas:
Permítanme citar la documentación oficial :
En tu caso es algo así como:
fuente
send
Mi caso fue diferente de la respuesta aceptada. Estaba tratando de burlarme de un método de paquete privado para una instancia que no vivía en ese paquete
y las clases de prueba
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.
fuente
En mi caso, usando Mockito 2.0, tuve que cambiar todos los
any()
parámetros anullable()
para detener la llamada real.fuente
foo = Mockito.spy(foo);
Mockito.doReturn(someValue).when(foo).methodToPrevent(nullable(ArgumentType.class));
any
yeq
coincidencias.¡La respuesta de Tomasz Nurkiewicz parece no contar toda la historia!
NB Versión Mockito: 1.10.19.
Soy un Mockito newb, así que no puedo explicar el siguiente comportamiento: si hay un experto por ahí que pueda mejorar esta respuesta, por favor siéntase libre.
El método en cuestión aquí, NO
getContentStringValue
es y NO .final
static
Esta línea hace llamar el método original
getContentStringValue
:Esta línea no llama al método original
getContentStringValue
:Por razones que no puedo responder, el uso
isA()
hacedoReturn
que falle el comportamiento pretendido (?) De "no llamar al método" .Veamos las firmas de métodos involucradas aquí: ambos son
static
métodos deMatchers
. El Javadoc dice que ambos regresannull
, lo cual es un poco difícil de entender. Presumiblemente, elClass
objeto pasado mientras se examina el parámetro, pero el resultado nunca se calculó ni se descartó. Dado quenull
puede representar cualquier clase y que espera que no se invoque el método simulado, ¿no podrían las firmasisA( ... )
yany( ... )
simplemente regresar ennull
lugar de un parámetro genérico *<T>
?De todas formas:
La documentación de la API no da ninguna pista sobre esto. También parece decir que la necesidad de tal comportamiento de "no llamar método" es "muy rara". Personalmente, uso esta técnica todo el tiempo : normalmente encuentro que las burlas implican unas pocas líneas que "preparan la escena" ... seguido de un método que luego "reproduce" la escena en el contexto simulado que has puesto en escena ... .y mientras está configurando el escenario y los accesorios, lo último que desea es que los actores entren al escenario a la izquierda y comiencen a actuar con el corazón ...
Pero esto está más allá de mi calificación salarial ... Invito a explicaciones de cualquier sumo sacerdote Mockito que pase ...
* ¿es "parámetro genérico" el término correcto?
fuente
Otro escenario posible que puede causar problemas con los espías es cuando está probando frijoles de primavera (con el marco de prueba de primavera) o algún otro marco que está proxing sus objetos durante la prueba .
Ejemplo
En el código anterior, Spring y Mockito intentarán representar su objeto MonitoringDocumentsRepository, pero Spring será el primero, lo que provocará una llamada real del método findMonitoringDocuments. Si depuramos nuestro código justo después de poner un espía en el objeto del repositorio, se verá así dentro del depurador:
@SpyBean al rescate
Si, en cambio
@Autowired
, usamos la@SpyBean
anotación, resolveremos el problema anterior, la anotación SpyBean también inyectará un objeto de repositorio, pero Mockito lo representará primero y se verá así dentro del depuradory aquí está el código:
fuente
He encontrado otra razón para que el espía llame al método original.
Alguien tuvo la idea de burlarse de una
final
clase y descubrió lo siguienteMockMaker
:Fuente: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
Después de fusionarme y traer ese archivo a mi máquina, mis pruebas fallaron.
Simplemente tuve que eliminar la línea (o el archivo) y
spy()
trabajé.fuente
Llegué un poco tarde a la fiesta, pero las soluciones anteriores no me funcionaron, así que compartir mi 0.02
Versión de Mokcito: 1.10.19
MyClass.java
Test.java
Lo siguiente NO funcionó para mí (se estaba llamando al método real):
1)
2)
3)
Siguiendo TRABAJADO:
fuente
Una forma de asegurarse de que no se llame a un método de una clase es anular el método con un ficticio.
fuente
Respuesta para usuarios de scala: ¡Incluso poner
doReturn
primero no funciona! Ver este post .fuente