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ę MockingProgressklasy 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 mockmetody Mockitoklasy, zasadniczo dzieje się tak:
Mockito.mockdelegaci do org.mockito.internal.MockitoCore.mock, przekazując domyślne ustawienia makiety jako parametr.
MockitoCore.mockdelegatów do org.mockito.internal.util.MockUtil.createMock
MockUtilKlasa wykorzystuje ClassPathLoaderklasę, aby uzyskać instancję MockMakerużyć do tworzenia makiety. Domyślnie używana jest klasa CgLibMockMaker .
CgLibMockMakerużywa klasy zapożyczonej z JMock, ClassImposterizerktóra obsługuje tworzenie makiety. Kluczowe elementy użytej „magii mockito” są MethodInterceptorużywane do tworzenia makiety: mockito MethodInterceptorFilteri ł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 MockHandlerinstancji, które ostatecznie są delegowane MockHandlerImpl#handle. Podczas MockHandlerImpl#handle, pozorna procedura obsługi tworzy instancję OngoingStubbingImpli przekazuje ją do udostępnionej MockingProgressinstancji.
Gdy whenmetoda 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 MockingProgressinstancji, do której method()zapisano fałszywe wywołanie, i zwraca je. Następnie thenReturnwywoływana jest metoda na OngoingStubbinginstancji.