kiedy uruchamiam test mockito, występuje wyjątek WrongTypeOfReturnValue

96

Szczegóły błędu:

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.

mój kod:

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

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

Jak widać, wzywam whenna updateItemAttributes(co nie zwracają boolean) nie na updateItemAttributesByJuId.

  1. Dlaczego Mockito próbuje zwrócić booleanod updateItemAttributesByJuId?
  2. Jak można to naprawić?
zdezorientowany dzwonek
źródło

Odpowiedzi:

199

Zgodnie z https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90 należy przeformułować

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

do

doReturn(fooBar).when(bar).getFoo()
gna
źródło
3
To świetna wskazówka. Miałem również ten problem podczas testowania @Repositorymetody Spring DAO z @Aspect . jeśli to zrobię when(someDao.someMethod()).thenReturn(List<xxx>), mam ten wyjątek WrongTypeOfReturnValue. Poprzez debugowanie widzę, że someMethodmetoda została faktycznie wywołana w powyższej instrukcji i wyzwala pomoc w zakresie nullokrążenia i zwraca, ale Mockito oczekuje List<xxx>.
LeOn - Han Li
U mnie wyszło. Obrigado!
Saksofonista
Doskonała odpowiedź. To uratowało mi dzień.
user3198259
U mnie też zadziałało! Dzięki! Chociaż nie w pełni zrozumiałem wyjaśnienie w podanym linku.
georgeliatsos
40

Innym powodem podobnego komunikatu o błędzie jest próba sfałszowania finalmetody. Nie należy próbować kpić z metod końcowych (patrz Mockowanie metod końcowych ).

Zmierzyłem się również z błędem w teście wielowątkowym. Odpowiedź przez gna zadziałała w tym przypadku.

zmiany Arvidaa
źródło
20

Bardzo ciekawy problem. W moim przypadku ten problem był spowodowany, gdy próbowałem debugować moje testy w tej podobnej linii:

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

Ważną informacją jest to, że testy działały poprawnie bez debugowania.

W każdym razie, kiedy zamieniłem powyższy kod na poniższy fragment kodu, mogłem bez problemu zdebugować problem.

doReturn(fooBar).when(bar).getFoo();
Łukasz
źródło
Dzięki, wygląda na to, że jest ten sam problem z klasami danych Kotlin jak z polami, a Twoje rozwiązanie go rozwiązało!
Mohsen Mirhoseini
6

Dla mnie oznaczało to, że prowadziłem to:

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

Więc co się dzieje, jest to, że Mockito było wykrycie, że a.method2()był nazywany, i mówi mi, że nie może wrócić cz a.method2()co jest źle.

Poprawka: użyj doReturn(c).when(b).method1(a)składni stylu (zamiast when(b.method1(a)).thenReturn(c);), która pomoże ci odkryć ukryty błąd bardziej zwięźle i szybciej.

Lub w tym konkretnym przypadku, po wykonaniu tej czynności, zaczął pokazywać dokładniejszy „NotAMockException” i zmieniłem go, aby nie próbował już ustawiać wartości zwracanej z obiektu niebędącego makietą.

rogerdpack
źródło
1
Ten sam błąd, który też popełniłem. Zakpiłem metodę używaną w method1, wykonałem i otrzymałem ten wyjątek. Problem został rozwiązany, gdy usunąłem ten kod.
Praveen.883
5

Niedawno miałem ten problem. Problem polegał na tym, że metoda, którą próbowałem wyszydzić, nie miała modyfikatora dostępu. Dodanie publicznego rozwiązało problem.

not_john
źródło
5

Miałem ten błąd, ponieważ w moim teście miałem dwa oczekiwania, jedno na próbę, a drugie na konkretny 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();

Naprawiłem to, zmieniając cls, aby były również próbą

Tzafrir
źródło
4

W moim przypadku problem był spowodowany próbą wyszydzenia metody statycznej i zapomnieniem wywołania mockStaticklasy. Zapomniałem też o dołączeniu tej klasy do@PrepareForTest()

ACV
źródło
2

Jeśli używasz adnotacji, może być konieczne użycie @Mock zamiast @InjectMocks. Ponieważ @InjectMocks działa razem jako @Spy i @Mock. @Spy śledzi ostatnio wykonane metody i możesz odnieść wrażenie, że zwracane są nieprawidłowe dane.

dillip pattnaik
źródło
2
@InjectMocksdziała jako @Spyi @Mockrazem”. <- to wydaje mi się złe. Skąd o tym słyszałeś?
Etienne Miret
2

W moim przypadku używałem obu @RunWith(MockitoJUnitRunner.class)i MockitoAnnotations.initMocks(this). Po usunięciu MockitoAnnotations.initMocks(this)działało poprawnie.

ihebiheb
źródło
1

Błąd:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Ciąg nie może zostać zwrócony przez size ()
size () powinien zwrócić int
***
Jeśli nie masz pewności, dlaczego otrzymujesz powyższy błąd, czytaj dalej.
Ze względu na charakter powyższej składni problem może wystąpić, ponieważ:
1. Ten wyjątek może wystąpić w błędnie napisanych
testach wielowątkowych .
Zapoznaj się z często zadawanymi pytaniami dotyczącymi Mockito na temat ograniczeń testowania współbieżności.
2. Szpieg jest blokowany przy użyciu składni when (spy.foo ()). Then (). Bezpieczniej jest zdeponować
szpiegów -
- przy użyciu rodziny metod doReturn | Throw (). Więcej w javadocs dla
metody Mockito.spy ().

Rzeczywisty kod:

@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

Rozwiązanie, aby rozwiązać ten problem:

1. Usuń adnotację „@Mock”.

private ByteString mockByteString;

2nd Add PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);
DHANDAYUTHAPANI MUNISAMY
źródło
1

Niedawno napotkałem ten problem podczas mockowania funkcji w klasie danych Kotlin . Z jakiegoś nieznanego powodu jeden z moich przebiegów testowych zakończył się zawieszeniem. Kiedy ponownie przeprowadziłem testy, niektóre z moich testów, które wcześniej przeszły, zaczęły kończyć się niepowodzeniem z WrongTypeOfReturnValuewyjątkiem.

org.mockito:mockito-inlineUpewniłem się, że używam, aby uniknąć problemów z końcowymi zajęciami (o których wspomniał Arvidaa), ale problem pozostał. Rozwiązaniem dla mnie było zabicie procesu i ponowne uruchomienie Android Studio . To zakończyło mój zamrożony przebieg testowy, a kolejne przebiegi testowe przeszły bez problemów.

simonevertsson
źródło
1

Brak @MockBean w fasoli, którą chcesz wyszydzić

budda
źródło
1

Mam ten problem, WrongTypeOfReturnValueponieważ wyszydziłem metodę zwracającą a java.util.Optional;z com.google.common.base.Optional;powodu automatycznego dodawania brakujących importów przez program formatujący.

Mockito właśnie powiedział mi, że „metoda coś () powinna zwrócić Opcjonalne” ...

RotS
źródło
1

W moim przypadku fasola została zainicjowana przy użyciu adnotacji @Autowired zamiast @MockBean

W ten sposób kpiny z DAO i usług rzucają taki wyjątek

S.Dayneko
źródło
1
Tak, w moim przypadku test usługi aplikacji Spring-Boot, MockBean powinien być używany podczas mockowania Beana. dzięki!
Isaac Philip
1

Dla mnie problemem były testy wielowątkowe, które wykonywały stubbing / weryfikację na udostępnionych makietach. Doprowadziło to do losowego wyrzucenia WrongTypeOfReturnValuewyjątku.

To nie jest poprawnie napisany test przy użyciu Mockito. Nie należy uzyskiwać dostępu do makiet z wielu wątków.

Rozwiązaniem było stworzenie makiet lokalnych dla każdego testu.

Damian
źródło
1

TL; DR Jeśli niektóre argumenty w twoim teście są null, pamiętaj, aby mockować wywołanie parametru za pomocą isNull()zamiast anyXXX().


Otrzymałem ten błąd podczas aktualizacji z Spring boot 1.5.x do 2.1.x. Spring boot jest dostarczany z własnym Mockito, które jest teraz również zaktualizowane do 2.x (patrz np. Zależności Spring boot 2.1.2 )

Mockito zmienił zachowanie dla anyXXX()sposobu, gdzie XXXjest String, Longitp Oto javadoc z anyLong():

Od Mockito 2.1.0 zezwalaj tylko na wartości Long, więc nullnie jest już prawidłową wartością. Ponieważ prymitywne opakowania dopuszczają wartość null, sugerowanym API do dopasowania null opakowania byłoby #isNull(). Uznaliśmy, że ta zmiana sprawi, że testy będą znacznie bezpieczniejsze niż w przypadku Mockito 1.x.

Sugerowałbym debugowanie do punktu, w którym twój makieta ma zostać wywołany i sprawdzenie, czy przynajmniej jeden argument jest null. W takim przypadku upewnij się, że przygotowujesz makietę isNull()zamiast np anyLong().

Więc to:

when(MockedClass.method(anyString());

staje się:

when(MockedClass.method(isNull());
Younes EO
źródło
-1

To jest moja sprawa:

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

Wtedy pojawia się ten błąd:

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

Czy możesz zgadnąć?

Problem polega na tym, że Target.method1 () jest metodą statyczną. Mockito całkowicie ostrzega mnie przed inną rzeczą.

Surasin Tancharoen
źródło