Krótka odpowiedź jest taka, że w twoim przykładzie wynik mock.method()
będzie odpowiednią dla typu wartością pustą; mockito używa pośrednictwa poprzez proxy, przechwytywanie metody i współdzieloną instancję MockingProgress
klasy w celu ustalenia, czy wywołanie metody na makiecie służy do wstawiania lub odtwarzania istniejącego zachowania, a nie do przekazywania informacji o skrótach za pośrednictwem wartości zwracanej wyszydzana metoda.
Mini-analiza w ciągu kilku minut patrząc na kod mockito jest następująca. Uwaga, jest to bardzo przybliżony opis - w grze jest wiele szczegółów. Sugeruję, abyś sam sprawdził źródło na githubie .
Po pierwsze, kiedy kpisz z klasy przy użyciu mock
metody Mockito
klasy, zasadniczo dzieje się tak:
Mockito.mock
delegaci do org.mockito.internal.MockitoCore
.mock, przekazując domyślne ustawienia makiety jako parametr.
MockitoCore.mock
delegatów do org.mockito.internal.util.MockUtil
.createMock
MockUtil
Klasa wykorzystuje ClassPathLoader
klasę, aby uzyskać instancję MockMaker
użyć do tworzenia makiety. Domyślnie używana jest klasa CgLibMockMaker .
CgLibMockMaker
używa klasy zapożyczonej z JMock, ClassImposterizer
która obsługuje tworzenie makiety. Kluczowe elementy użytej „magii mockito” są MethodInterceptor
używane do tworzenia makiety: mockito MethodInterceptorFilter
i łańcuch instancji MockHandler, w tym instancja MockHandlerImpl . Przechwytywacz metody przekazuje wywołania do instancji MockHandlerImpl, która implementuje logikę biznesową, która powinna być zastosowana, gdy metoda jest wywoływana na makiecie (tj. Wyszukuje, czy odpowiedź została już zarejestrowana, czy wywołanie reprezentuje nowy kod pośredniczący itp. Stan domyślny jest taki, że jeśli kod pośredniczący nie jest jeszcze zarejestrowany dla wywoływanej metody, zwracana jest pusta wartość odpowiednia dla typu .
Spójrzmy teraz na kod w Twoim przykładzie:
when(mock.method()).thenReturn(someValue)
Oto kolejność, w jakiej ten kod będzie wykonywany:
mock.method()
when(<result of step 1>)
<result of step 2>.thenReturn
Kluczem do zrozumienia tego, co się dzieje, jest to, co się dzieje, gdy wywoływana jest metoda na makiecie: przechwytywacz metody przekazuje informacje o wywołaniu metody i deleguje je do łańcucha MockHandler
instancji, które ostatecznie są delegowane MockHandlerImpl#handle
. Podczas MockHandlerImpl#handle
, pozorna procedura obsługi tworzy instancję OngoingStubbingImpl
i przekazuje ją do udostępnionej MockingProgress
instancji.
Gdy when
metoda jest wywoływana po wywołaniu method()
, jest delegowana do MockitoCore.when
, co wywołuje stub()
metodę tej samej klasy. Ta metoda rozpakowuje trwający kod pośredniczący ze współużytkowanej MockingProgress
instancji, do której method()
zapisano fałszywe wywołanie, i zwraca je. Następnie thenReturn
wywoływana jest metoda na OngoingStubbing
instancji.