cuando ejecuto la prueba de mockito ocurre una excepción WrongTypeOfReturnValue

96

Detalle del error:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Boolean cannot be returned by updateItemAttributesByJuId()
updateItemAttributesByJuId() should return ResultRich
This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.

mi código :

@InjectMocks
protected ItemArrangeManager arrangeManagerSpy = spy(new ItemArrangeManagerImpl());
@Mock
protected JuItemWriteService juItemWriteService;

when(arrangeManagerSpy
    .updateItemAttributes(mapCaptor.capture(), eq(juId), eq(itemTO.getSellerId())))
    .thenReturn(false);

Como puede ver, estoy llamando whena updateItemAttributes(que devuelve a boolean) no a updateItemAttributesByJuId.

  1. ¿Por qué Mockito intenta devolver un booleande updateItemAttributesByJuId?
  2. ¿Cómo se puede rectificar esto?
campanilla confundida
fuente

Respuestas:

199

Según https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 , debe reformular su

when(bar.getFoo()).thenReturn(fooBar)

a

doReturn(fooBar).when(bar).getFoo()
gna
fuente
3
Este es un gran consejo. También estaba teniendo este problema al probar algún @Repositorymétodo Spring DAO con @Aspect . si lo hago when(someDao.someMethod()).thenReturn(List<xxx>), tengo esta excepción WrongTypeOfReturnValue. A través de la depuración, puedo ver que en someMethodrealidad se ha llamado al método en la declaración anterior y activa el consejo de vuelta y devuelve un nullpero Mockito espera un List<xxx>.
LeOn - Han Li
Funcionó para mí. ¡Obrigado!
Saxofonista
Excelente respuesta. Ha salvado mi día.
user3198259
¡Funcionó también para mí! ¡Gracias! Aunque no entendí completamente la explicación en el enlace proporcionado.
georgeliatsos
40

Otra razón para un mensaje de error similar es intentar simular un finalmétodo. Uno no debería intentar burlarse de los métodos finales (ver Burla del método final ).

También me he enfrentado al error en una prueba de subprocesos múltiples. La respuesta de gna funcionó en ese caso.

Arvidaa
fuente
20

Problema muy interesado. En mi caso, este problema fue causado cuando intenté depurar mis pruebas en esta línea similar:

Boolean fooBar;
when(bar.getFoo()).thenReturn(fooBar);

La nota importante es que las pruebas se ejecutaron correctamente sin depurar.

De cualquier manera, cuando reemplacé el código anterior con el siguiente fragmento de código, pude depurar la línea del problema sin problemas.

doReturn(fooBar).when(bar).getFoo();
Luke
fuente
Gracias, parece que hay el mismo problema con las clases de datos de Kotlin como campos, ¡y su solución lo resolvió!
Mohsen Mirhoseini
6

Para mí, esto significaba que estaba ejecutando esto:

a = Mockito.mock(SomeClass.class);
b = new RealClass();
when(b.method1(a)).thenReturn(c); 
// within this method1, it calls param1.method2() -- note, b is not a spy or mock

Entonces lo que estaba sucediendo es que Mockito estaba detectando que a.method2()estaba siendo llamado y me decía que no podía regresar cde lo a.method2()que estaba mal.

Solución: use la doReturn(c).when(b).method1(a)sintaxis de estilo (en lugar de when(b.method1(a)).thenReturn(c);), que lo ayudará a descubrir el error oculto de manera más concisa y rápida.

O en este caso particular, después de hacer eso, comenzó a mostrar la "NotAMockException" más precisa, y la cambié para que ya no intente establecer un valor de retorno de un objeto no simulado.

Rogerdpack
fuente
1
El mismo error que yo también cometí. Me burlé del método utilizado en el método 1, lo ejecuté y obtuve esta excepción. Se resolvió una vez que eliminé ese código.
Praveen.883
5

Recientemente tuve este problema. El problema era que el método que intentaba simular no tenía modificador de acceso. Agregar público resolvió el problema.

not_john
fuente
5

Tuve este error porque en mi prueba tenía dos expectativas, una en un simulacro y otra en tipo concreto

MyClass cls = new MyClass();
MyClass cls2 = Mockito.mock(Myclass.class);
when(foo.bar(cls)).thenReturn(); // cls is not actually a mock
when(foo.baz(cls2)).thenReturn();

Lo arreglé cambiando cls para que sea una simulación también

Tzafrir
fuente
4

En mi caso, el problema fue causado por intentar simular un método estático y olvidarme de llamar mockStatica la clase. También olvidé incluir la clase en el@PrepareForTest()

ACV
fuente
2

Si está usando anotaciones, es posible que necesite usar @Mock en lugar de @InjectMocks. Porque @InjectMocks funciona como @Spy y @Mock juntos. Y @Spy realiza un seguimiento de los métodos ejecutados recientemente y es posible que sienta que se devuelven / sustituyen datos incorrectos.

Dillip Pattnaik
fuente
2
" @InjectMocksfunciona como @Spyy @Mockjuntos". <- eso me parece mal. ¿De dónde escuchaste esto?
Etienne Miret
2

En mi caso, estaba usando ambos @RunWith(MockitoJUnitRunner.class)y MockitoAnnotations.initMocks(this). Cuando lo quité MockitoAnnotations.initMocks(this)funcionó correctamente.

ihebiheb
fuente
1

Error:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: La
cadena no se puede devolver por size ()
size () debe devolver int
***
Si no está seguro de por qué está obteniendo el error anterior, siga leyendo.
Debido a la naturaleza de la sintaxis anterior, el problema puede ocurrir porque:
1. Esta excepción puede ocurrir en
pruebas de subprocesos múltiples mal escritas .
Consulte las preguntas frecuentes de Mockito sobre las limitaciones de las pruebas de concurrencia.
2. Un espía es eliminado usando la sintaxis when (spy.foo ()). Then (). Es más seguro hacer
stub a espías -
- con la familia de métodos doReturn | Throw (). Más en javadocs para el
método Mockito.spy ().

Código real:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Object.class, ByteString.class})

@Mock
private ByteString mockByteString;

String testData = “dsfgdshf”;
PowerMockito.when(mockByteString.toStringUtf8()).thenReturn(testData); 
// throws above given exception

Solución para solucionar este problema:

1º Eliminar la anotación “@Mock”.

private ByteString mockByteString;

2do Agregar PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);
MUNISAMIO DE DHANDAYUTHAPANI
fuente
1

Recientemente encontré este problema mientras me burlaba de una función en una clase de datos de Kotlin . Por alguna razón desconocida, una de mis ejecuciones de prueba terminó en un estado congelado. Cuando volví a ejecutar las pruebas, algunas de mis pruebas que habían pasado anteriormente comenzaron a fallar con la WrongTypeOfReturnValueexcepción.

Me aseguré de que estaba usando org.mockito:mockito-inlinepara evitar los problemas con las clases finales (mencionado por Arvidaa), pero el problema persistió. Lo que me resolvió fue matar el proceso y reiniciar Android Studio . Esto terminó mi ejecución de prueba congelada y las siguientes ejecuciones de prueba pasaron sin problemas.

simonevertsson
fuente
1

Falta @MockBean en el bean que quieres burlarte

Buda
fuente
1

Tengo este problema WrongTypeOfReturnValueporque me burlé de un método que devuelve un java.util.Optional;con un com.google.common.base.Optional;debido a que mi formateador agrega automáticamente las importaciones faltantes.

Mockito me estaba diciendo que "el método algo () debería devolver Opcional" ...

Putrefacción
fuente
1

En mi caso, el bean se ha inicializado usando la anotación @Autowired en lugar de @MockBean

Entonces, de esta manera, burlarse de DAO y Servicios arroja tal excepción

S. Dayneko
fuente
1
Sí, en mi caso, una prueba de servicio de la aplicación Spring-Boot, MockBean debe usarse al burlarse de un Bean. ¡Gracias!
Isaac Philip
1

Para mí, el problema eran las pruebas multiproceso que estaban haciendo stubbing / verificación en simulaciones compartidas. Condujo a lanzar WrongTypeOfReturnValueexcepciones al azar .

Esta no es una prueba escrita correctamente usando Mockito. No se debe acceder a los simulacros desde varios hilos.

La solución fue hacer simulaciones locales para cada prueba.

Damian
fuente
1

TL; DR Si algunos argumentos en su prueba lo son null, asegúrese de simular la llamada al parámetro con en isNull()lugar de anyXXX().


Recibí este error al actualizar de Spring boot 1.5.xa 2.1.x. Spring boot viene con su propio Mockito, que ahora también está actualizado a 2.x (ver, por ejemplo, Dependencias de Spring boot 2.1.2 )

Mockito ha cambiado el comportamiento del anyXXX()método, donde XXXes String, Long, etc Aquí está el Javadoc de anyLong():

Desde Mockito 2.1.0, solo permite valuado Long, por nulllo que ya no es un valor válido. Como los envoltorios primitivos son anulables, la API sugerida para coincidir con el null envoltorio sería #isNull(). Sentimos que este cambio haría que las pruebas fueran mucho más seguras que con Mockito 1.x.

Le sugiero que depure hasta el punto en que su simulacro esté a punto de ser llamado e inspeccione si al menos un argumento lo es null. En ese caso, asegúrese de preparar su simulacro en isNull()lugar de, por ejemplo anyLong().

Así que esto:

when(MockedClass.method(anyString());

se convierte en:

when(MockedClass.method(isNull());
Younes EO
fuente
-1

Este es mi caso:

//given
ObjectA a = new ObjectA();
ObjectB b = mock(ObjectB.class);
when(b.call()).thenReturn(a);

Target target = spy(new Target());
doReturn(b).when(target).method1();

//when
String result = target.method2();

Entonces me sale este error:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
ObjectB$$EnhancerByMockitoWithCGLIB$$2eaf7d1d cannot be returned by method2()
method2() should return String

¿Puedes adivinar?

El problema es que Target.method1 () es un método estático. Mockito me advierte completamente de otra cosa.

Surasin Tancharoen
fuente