Używam Mockito 1.9.0. Chcę kpić zachowanie dla jednej metody klasy w teście JUnit, więc mam
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
Problem polega na tym, że w drugiej linii myClassSpy.method1()
jest wywoływany, co powoduje wyjątek. Jedynym powodem, dla którego używam makiet, jest to, że później, przy każdym myClassSpy.method1()
wywołaniu, nie zostanie wywołana prawdziwa metoda i myResults
obiekt zostanie zwrócony.
MyClass
jest interfejsem i myInstance
jest jego implementacją, jeśli to ma znaczenie.
Co muszę zrobić, aby poprawić to zachowanie szpiegowskie?
Odpowiedzi:
Pozwól mi zacytować oficjalną dokumentację :
W twoim przypadku wygląda to tak:
źródło
send
Moja sprawa różni się od przyjętej odpowiedzi. Próbowałem wyśmiewać metodę private-package dla instancji, która nie istniała w tym pakiecie
i klasy testowe
Kompilacja jest poprawna, ale gdy próbuje skonfigurować test, zamiast tego wywołuje prawdziwą metodę.
Deklaracja metody chronionej lub publicznej rozwiązuje problem, ponieważ nie jest to czyste rozwiązanie.
źródło
W moim przypadku, używając Mockito 2.0, musiałem zmienić wszystkie
any()
parametry, aby zgasićnullable()
prawdziwe połączenie.źródło
foo = Mockito.spy(foo);
Mockito.doReturn(someValue).when(foo).methodToPrevent(nullable(ArgumentType.class));
any
ieq
dopasowuje.Odpowiedź Tomasza Nurkiewicza wydaje się nie opowiadać całej historii!
Uwaga: wersja Mockito: 1.10.19.
Jestem bardzo nowicjuszem Mockito, więc nie potrafię wyjaśnić następującego zachowania: jeśli istnieje ekspert, który może poprawić tę odpowiedź, nie krępuj się.
Metoda, o której tu mowa
getContentStringValue
, NIE jestfinal
i NIEstatic
.Linia ta ma wywołać oryginalną metodę
getContentStringValue
:Ta linia nie wywołuje oryginalnej metody
getContentStringValue
:Z powodów, na które nie mogę odpowiedzieć, użycie
isA()
powoduje, że zamierzone (?) Działanie „nie wywoływać metody”doReturn
nie powiodło się.Spójrzmy na użyte tutaj podpisy metod: obie są
static
metodamiMatchers
. Obaj mówią Javadoc o powrocienull
, co jest trochę trudne do opanowania w sobie. PrawdopodobnieClass
obiekt przekazany podczas badania parametru jest badany, ale wynik nigdy nie jest obliczany ani odrzucany. Jeśli się uwzględninull
może to oznaczać dowolną klasę i że liczysz na to, że wyśmiewana metoda nie zostanie wywołana, czy podpisyisA( ... )
iany( ... )
po prostu nie zwrócą sięnull
zamiast parametru ogólnego *<T>
?Tak czy siak:
Dokumentacja API nie daje żadnych wskazówek na ten temat. Wydaje się również, że potrzeba takiego zachowania „nie wywoływać metody” jest „bardzo rzadka”. Ja osobiście używam tej techniki przez cały czas : zazwyczaj uważam, że kpina obejmuje kilka linii, które „ustawiają scenę” ... a następnie wywołuje metodę, która następnie „odtwarza” scenę w symulowanym kontekście, który wystawiłeś… Podczas gdy ustawiasz scenerię i rekwizyty, ostatnią rzeczą, jakiej pragniesz, jest, aby aktorzy weszli na scenę po lewej i zaczęli grać swoje serca ...
Ale to znacznie wykracza poza moją pensję ... Zapraszam wyjaśnienia od wszystkich przechodzących arcykapłanów Mockito ...
* czy „parametr ogólny” jest właściwym terminem?
źródło
Kolejnym możliwym scenariuszem, który może powodować problemy ze szpiegami, jest testowanie fasoli szparagowej (z ramą testu wiosennego) lub innej struktury, która przybliża obiekty podczas testu .
Przykład
W powyższym kodzie zarówno Spring, jak i Mockito będą próbowały proxy twojego obiektu MonitoringDocumentsRepository, ale Spring będzie pierwszy, co spowoduje prawdziwe wywołanie metody findMonitoringDocuments. Jeśli debugujemy nasz kod tuż po umieszczeniu szpiega w obiekcie repozytorium, będzie on wyglądał następująco:
@SpyBean na ratunek
Jeśli zamiast
@Autowired
adnotacji użyjemy@SpyBean
adnotacji, rozwiążemy powyższy problem, adnotacja SpyBean również wstrzykuje obiekt repozytorium, ale najpierw będzie proxy przez Mockito i będzie wyglądać jak ten wewnątrz debuggeraa oto kod:
źródło
Znalazłem jeszcze jeden powód, dla którego szpieg wywołuje oryginalną metodę.
Ktoś wpadł na pomysł, aby wyśmiewać
final
klasę i dowiedział się oMockMaker
:Źródło: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
Po scaleniu i przeniesieniu tego pliku na mój komputer moje testy zakończyły się niepowodzeniem.
Musiałem tylko usunąć linię (lub plik) i
spy()
działałem.źródło
Trochę późno na imprezę, ale powyższe rozwiązania nie działały dla mnie, więc dzielę się 0,02 $
Wersja Mokcito: 1.10.19
MyClass.java
Test.java
Poniższe NIE działało dla mnie (wywoływano rzeczywistą metodę):
1.
2)
3)
Po DZIAŁANIU:
źródło
Jednym ze sposobów upewnienia się, że metoda z klasy nie jest wywoływana, jest przesłonięcie metody za pomocą manekina.
źródło
Odpowiedź dla użytkowników Scali: Nawet stawianie na
doReturn
pierwszym miejscu nie działa! Zobacz ten post .źródło