lorsque j'exécute un test mockito se produit WrongTypeOfReturnValue Exception


94

Détail de l'erreur:

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.

mon code:

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

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

Comme vous pouvez le voir, j'appelle whensur updateItemAttributes(ce qui renvoie a boolean) pas sur updateItemAttributesByJuId.

  1. Pourquoi Mockito tente-t-il de renvoyer un booleande updateItemAttributesByJuId?
  2. Comment cela peut-il être rectifié?

Réponses:


190

Selon https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 , vous devez reformuler votre

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

à

doReturn(fooBar).when(bar).getFoo()

3
C'est un bon conseil. J'avais également ce problème lors du test d'une @Repositoryméthode Spring DAO avec @Aspect . si je le fais when(someDao.someMethod()).thenReturn(List<xxx>), j'ai cette exception WrongTypeOfReturnValue. Grâce au débogage, je peux voir que la someMethodméthode est en fait appelée dans l'instruction ci-dessus et déclenche le conseil Around et renvoie un nullmais Mockito attend un List<xxx>.
LeOn - Han Li

Ça a marché pour moi. Obrigado!
Saxophoniste

Excellente réponse. C'est sauvé ma journée.
user3198259 le

40

Une autre raison pour un message d'erreur similaire est d'essayer de se moquer d'une finalméthode. Il ne faut pas essayer de se moquer des méthodes finales (voir Moquages ​​de la méthode finale ).

J'ai également confronté l'erreur dans un test multi-thread. Réponse de gna a fonctionné dans ce cas.


19

Problème très intéressant. Dans mon cas, ce problème a été causé lorsque j'ai essayé de déboguer mes tests sur cette ligne similaire:

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

La remarque importante est que les tests s'exécutaient correctement sans débogage.

De toute façon, lorsque j'ai remplacé le code ci-dessus par l'extrait de code ci-dessous, j'ai pu déboguer la ligne de problème sans problème.

doReturn(fooBar).when(bar).getFoo();

Merci, il semble qu'il y ait le même problème avec les classes de données Kotlin que les champs, et votre solution l'a résolu!
Mohsen Mirhoseini

6

Pour moi, cela signifiait que je dirigeais ceci:

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

Donc, ce qui se passait, c'est que mockito détectait qui a.method2()était appelé, et me disait que je ne pouvais pas revenir cde a.method2()ce qui était faux.

Correction: utilisez la doReturn(c).when(b).method1(a)syntaxe de style (au lieu de when(b.method1(a)).thenReturn(c);), qui vous aidera à découvrir le bogue caché de manière plus concise et plus rapide.

Ou dans ce cas particulier, après avoir fait cela, il a commencé à afficher le "NotAMockException" plus précis, et je l'ai changé pour ne plus essayer de définir une valeur de retour à partir d'un objet non simulé.


1
Même erreur que moi aussi. Je me suis moqué de la méthode utilisée dans method1, exécuté et j'ai obtenu cette exception. Il a été résolu une fois que j'ai supprimé ce code.
Praveen.883

5

J'ai récemment eu ce problème. Le problème était que la méthode que j'essayais de simuler n'avait pas de modificateur d'accès. L'ajout de public a résolu le problème.


5

J'ai eu cette erreur car dans mon test j'avais deux attentes, une sur une maquette et une sur le type de béton

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();

Je l'ai corrigé en changeant les cls pour être également un simulacre


4

Dans mon cas, le problème a été causé en essayant de se moquer d'une méthode statique et en oubliant d'appeler mockStaticla classe. J'ai également oublié d'inclure la classe dans le@PrepareForTest()


2

Si vous utilisez des annotations, vous devrez peut-être utiliser @Mock au lieu de @InjectMocks. Parce que @InjectMocks fonctionne ensemble comme @Spy et @Mock. Et @Spy garde une trace des méthodes récemment exécutées et vous pouvez avoir l'impression que des données incorrectes sont renvoyées / sous-titrées.


2
" @InjectMocksfonctionne comme @Spyet @Mockensemble." <- cela me semble faux. D'où avez-vous entendu cela?
Etienne Miret

2

Dans mon cas, j'utilisais à la fois @RunWith(MockitoJUnitRunner.class)et MockitoAnnotations.initMocks(this). Quand j'ai enlevé MockitoAnnotations.initMocks(this)cela a fonctionné correctement.


2

Dans mon cas, le bean a été initialisé en utilisant l' annotation @Autowired au lieu de @MockBean

Donc, de cette façon, la moquerie des DAO et des services lève une telle exception


1
Oui, dans mon cas, un test de service d'application Spring-Boot, MockBean doit être utilisé lors de la simulation d'un Bean. Merci!
Isaac Philip

1

Erreur:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: La
chaîne ne peut pas être retournée par size ()
size () devrait retourner int
***
Si vous ne savez pas pourquoi vous obtenez l'erreur ci-dessus, lisez la suite.
En raison de la nature de la syntaxe ci-dessus, un problème peut survenir car:
1. Cette exception peut se produire dans des
tests multithreads mal écrits .
Veuillez vous référer à la FAQ Mockito sur les limites des tests de concurrence.
2. Un espion est stubblé en utilisant la syntaxe when (spy.foo ()). Then (). Il est plus sûr de
stub espions -
- avec la famille de méthodes doReturn | Throw (). Plus d'informations dans javadocs pour la
méthode Mockito.spy ().

Code réel:

@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

Solution pour résoudre ce problème:

1er Supprimer l'annotation «@Mock».

private ByteString mockByteString;

2e ajout PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);

1

J'ai récemment rencontré ce problème en se moquant d'une fonction dans une classe de données Kotlin . Pour une raison inconnue, l'un de mes tests s'est terminé dans un état figé. Lorsque j'ai réexécuté les tests, certains de mes tests qui avaient déjà réussi ont commencé à échouer avec l' WrongTypeOfReturnValueexception.

Je me suis assuré que j'utilisais org.mockito:mockito-inlinepour éviter les problèmes avec les classes finales (mentionnés par Arvidaa), mais le problème est resté. Ce qui a résolu le problème pour moi, c'est d' arrêter le processus et de redémarrer Android Studio . Cela a mis fin à mon test gelé et les tests suivants ont réussi sans problème.


1

@MockBean manquant sur le haricot dont vous voulez vous moquer


1

J'ai eu ce problème WrongTypeOfReturnValueparce que je me suis moqué d'une méthode renvoyant un java.util.Optional;avec un com.google.common.base.Optional;dû à mon formateur ajoutant automatiquement les importations manquantes.

Mockito me disait juste que "méthode quelque chose () devrait retourner facultatif" ...


1

Pour moi, le problème était les tests multithreads qui faisaient du stubbing / vérification sur une maquette partagée. Cela a conduit à lancer une WrongTypeOfReturnValueexception au hasard .

Ce test n'est pas correctement rédigé avec Mockito. Les mocks ne doivent pas être accessibles à partir de plusieurs threads.

La solution était de faire des simulations locales à chaque test.


1

TL; DR Si certains arguments de votre test le sont null, veillez à simuler l'appel de paramètre avec isNull()au lieu de anyXXX().


J'ai eu cette erreur lors de la mise à niveau de Spring Boot 1.5.x vers 2.1.x. Spring boot est livré avec son propre Mockito, qui est maintenant également mis à niveau vers 2.x (voir par exemple Dépendances de Spring boot 2.1.2 )

Mockito a changé le comportement de la anyXXX()méthode, où XXXest String, Longetc. Voici les Javadoc anyLong():

Depuis Mockito 2.1.0, autoriser uniquement les valeurs Long, nulln'est donc plus une valeur valide. Comme les wrappers primitifs peuvent être Nullables, l'API suggérée pour faire correspondre le null wrapper serait #isNull(). Nous avons estimé que ce changement rendrait les tests de harnais beaucoup plus sûrs qu'avec Mockito 1.x.

Je vous suggère de déboguer au point où votre maquette est sur le point d'être appelée et d'inspecter, si au moins un argument l'est null. Dans ce cas, assurez-vous que vous préparez votre maquette avec isNull()au lieu de par exemple anyLong().

Donc ça:

when(MockedClass.method(anyString());

devient:

when(MockedClass.method(isNull());

-1

C'est mon cas:

//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();

Ensuite, j'obtiens cette erreur:

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

Peux-tu deviner?

Le problème est que Target.method1 () est une méthode statique. Mockito me prévient complètement d'une autre chose.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.