Wenn ich einen Mockito-Test ausführe, tritt eine WrongTypeOfReturnValue-Ausnahme auf

93

Fehlerdetail:

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.

Mein Code:

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

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

Wie Sie sehen können, rufe ich whenan updateItemAttributes(was a zurückgibt boolean), nicht an updateItemAttributesByJuId.

  1. Warum versucht Mockito, einen booleanvon zurückzugeben updateItemAttributesByJuId?
  2. Wie kann dies behoben werden?
verwirrte Windglocke
quelle

Antworten:

187

Laut https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 sollten Sie Ihre umformulieren

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

zu

doReturn(fooBar).when(bar).getFoo()
gna
quelle
3
Das ist ein toller Tipp. Ich hatte dieses Problem auch beim Testen einer Spring @RepositoryDAO-Methode mit @Aspect . Wenn ich das tue when(someDao.someMethod()).thenReturn(List<xxx>), habe ich diese WrongTypeOfReturnValue-Ausnahme. Durch das Debuggen kann ich sehen, dass die someMethodMethode in der obigen Anweisung tatsächlich aufgerufen wurde und den Around Advice auslöst und a nullzurückgibt, aber Mockito erwartet a List<xxx>.
LeOn - Han Li
Hat für mich geklappt. Obrigado!
Saxophonist
39

Ein weiterer Grund für eine ähnliche Fehlermeldung ist der Versuch, eine finalMethode zu verspotten . Man sollte nicht versuchen, endgültige Methoden zu verspotten (siehe Verspotten der endgültigen Methode ).

Ich habe den Fehler auch in einem Multithread-Test konfrontiert. Die Antwort von gna hat in diesem Fall funktioniert.

Arvidaa
quelle
17

Sehr interessiertes Problem. In meinem Fall wurde dieses Problem verursacht, als ich versuchte, meine Tests in dieser ähnlichen Zeile zu debuggen:

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

Der wichtige Hinweis ist, dass die Tests ohne Debugging korrekt ausgeführt wurden.

In jedem Fall konnte ich die Problemzeile ohne Probleme debuggen, als ich den obigen Code durch den folgenden Code-Snippet ersetzte.

doReturn(fooBar).when(bar).getFoo();
Luke
quelle
Vielen Dank. Es sieht so aus, als gäbe es bei Kotlin-Datenklassen das gleiche Problem wie bei Feldern, und Ihre Lösung hat es gelöst!
Mohsen Mirhoseini
4

Ich hatte vor kurzem dieses Problem. Das Problem war, dass die Methode, die ich verspotten wollte, keinen Zugriffsmodifikator hatte. Das Hinzufügen von public löste das Problem.

not_john
quelle
4

Für mich bedeutete dies, dass ich Folgendes ausführte:

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

Also , was passiert war , dass Mockito ist wurde erfasst wird, dass a.method2()genannt wurde, und mir zu sagen , ich nicht zurückkehren konnte caus a.method2()dem falsch ist.

Fix: Verwenden Sie die doReturn(c).when(b).method1(a)Stilsyntax (anstelle von when(b.method1(a)).thenReturn(c);), um den versteckten Fehler präziser und schneller zu entdecken.

In diesem speziellen Fall wurde danach die genauere "NotAMockException" angezeigt, und ich habe sie so geändert, dass nicht mehr versucht wird, einen Rückgabewert für ein nicht nachgebildetes Objekt festzulegen.

Rogerdpack
quelle
1
Der gleiche Fehler, den ich auch gemacht habe. Ich habe die in Methode1 verwendete Methode verspottet, ausgeführt und diese Ausnahme erhalten. Es wurde behoben, als ich diesen Code entfernte.
Praveen.883
4

Ich hatte diesen Fehler, weil ich in meinem Test zwei Erwartungen hatte, eine an einen Schein und eine an einen konkreten Typ

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

Ich habe es behoben, indem ich cls so geändert habe, dass es auch ein Mock ist

Tzafrir
quelle
3

In meinem Fall wurde das Problem durch den Versuch verursacht, eine statische Methode zu verspotten und zu vergessen, mockStaticdie Klasse aufzurufen . Außerdem habe ich vergessen, die Klasse in die Klasse aufzunehmen@PrepareForTest()

ACV
quelle
1

Wenn Sie Anmerkungen verwenden, müssen Sie möglicherweise @Mock anstelle von @InjectMocks verwenden. Weil @InjectMocks als @Spy und @Mock zusammenarbeitet. Und @Spy verfolgt kürzlich ausgeführte Methoden und Sie haben möglicherweise das Gefühl, dass falsche Daten zurückgegeben / unterbettet werden.

Dillip Pattnaik
quelle
2
" @InjectMocksarbeitet als @Spyund @Mockzusammen." <- das scheint mir falsch zu sein. Woher hast du das gehört?
Etienne Miret
1

Fehlende @MockBean auf der Bean, die Sie verspotten möchten

Buddha
quelle
1

In meinem Fall habe ich beide @RunWith(MockitoJUnitRunner.class)und verwendet MockitoAnnotations.initMocks(this). Als ich es entfernte MockitoAnnotations.initMocks(this), funktionierte es richtig.

ihebiheb
quelle
1

In meinem Fall wurde die Bean mit @Autowired Annotation anstelle von @MockBean initialisiert

Auf diese Weise löst das Verspotten von DAOs und Diensten eine solche Ausnahme aus

S.Dayneko
quelle
0

Error:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
String kann nicht von size () zurückgegeben werden
size () sollte int zurückgeben
***
Wenn Sie sich nicht sicher sind, warum Sie über den Fehler hinausgehen , lesen Sie weiter.
Aufgrund der Art der obigen Syntax kann das folgende Problem auftreten:
1. Diese Ausnahme kann bei falsch geschriebenen Multithread-
Tests auftreten.
Informationen zu den Einschränkungen beim Testen der Parallelität finden Sie in den häufig gestellten Fragen zu Mockito.
2. Ein Spion wird mit der Syntax when (spy.foo ()). Then () gestoppt. Es ist sicherer,
Spione -
- mit der Methodenfamilie doReturn | Throw () zu stoppen. Mehr in javadocs für die
Mockito.spy () -Methode.

Aktueller Code:

@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

Lösung zur Behebung dieses Problems:

1. Entfernen Sie die Anmerkung „@Mock“.

private ByteString mockByteString;

2. Hinzufügen PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);
DHANDAYUTHAPANI MUNISAMY
quelle
0

Ich bin kürzlich auf dieses Problem gestoßen, als ich eine Funktion in einer Kotlin-Datenklasse verspottet habe . Aus einem unbekannten Grund endete einer meiner Testläufe in einem eingefrorenen Zustand. Als ich die Tests erneut ausführte, schlugen einige meiner zuvor bestandenen Tests mit der WrongTypeOfReturnValueAusnahme fehl .

Ich stellte sicher, dass ich org.mockito:mockito-inlinedie Probleme mit den Abschlussklassen (von Arvidaa erwähnt) vermieden hatte, aber das Problem blieb bestehen. Was es für mich gelöst hat, war , den Prozess abzubrechen und Android Studio neu zu starten . Dies beendete meinen eingefrorenen Testlauf und die folgenden Testläufe wurden ohne Probleme bestanden.

simonevertsson
quelle
0

Ich habe dieses Problem erhalten, WrongTypeOfReturnValueweil ich eine Methode verspottet habe, die a java.util.Optional;mit a com.google.common.base.Optional;zurückgibt, weil mein Formatierer automatisch fehlende Importe hinzugefügt hat.

Mockito sagte mir nur, dass "Methode etwas () Optional zurückgeben sollte" ...

RotS
quelle
0

Für mich waren das Problem die Multithread-Tests, die Stubbing / Verifikation auf einem gemeinsam genutzten Mock durchführten. Es führte zu zufälligen WrongTypeOfReturnValueAusnahmen.

Dies ist kein ordnungsgemäß geschriebener Test mit Mockito. Auf Mocks sollte nicht über mehrere Threads zugegriffen werden.

Die Lösung bestand darin, für jeden Test lokale Verspottungen vorzunehmen.

Damian
quelle
0

TL; DR Wenn einige Argumente in Ihrem Test nullvorliegen, verspotten Sie den Parameteraufruf mit isNull()statt anyXXX().


Ich habe diesen Fehler beim Upgrade von Spring Boot 1.5.x auf 2.1.x erhalten. Spring Boot wird mit einem eigenen Mockito ausgeliefert, der jetzt auch auf 2.x aktualisiert wird (siehe z. B. Abhängigkeiten von Spring Boot 2.1.2 ).

Mockito hat das Verhalten für die geänderte anyXXX()Methode, wo XXXist String, Longusw. Dies ist die javadoc von anyLong():

Da Mockito 2.1.0, erlauben nur geschätzt Long, so nullist nicht mehr ein gültiger Wert als primitive Wrapper nullable sind, die vorgeschlagene API entsprechen null würde Wrapper sein #isNull(). Wir waren der Meinung, dass diese Änderung das Testgeschirr viel sicherer machen würde als bei Mockito 1.x.

Ich würde vorschlagen, dass Sie bis zu dem Punkt debuggen, an dem Ihr Mock aufgerufen wird, und prüfen, ob mindestens ein Argument vorliegt null. Stellen Sie in diesem Fall sicher, dass Sie Ihren Mock mit isNull()statt z anyLong().

Also das:

when(MockedClass.method(anyString());

wird:

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

Das ist mein Fall:

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

Dann bekomme ich diesen Fehler:

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

Können Sie erraten?

Das Problem ist, dass Target.method1 () eine statische Methode ist. Mockito warnt mich völlig vor einer anderen Sache.

Surasin Tancharoen
quelle