Die kurze Antwort lautet, dass in Ihrem Beispiel das Ergebnis von mock.method()
ein typgerechter leerer Wert ist. mockito verwendet die Indirektion über Proxy, Abfangen von Methoden und eine gemeinsam genutzte Instanz der MockingProgress
Klasse, um zu bestimmen, ob ein Aufruf einer Methode auf einem Mock zum Stubben oder Wiedergeben eines vorhandenen Stubbed-Verhaltens dient, anstatt Informationen über das Stubbing über den Rückgabewert von zu übergeben eine verspottete Methode.
Eine Mini-Analyse in wenigen Minuten mit Blick auf den Mockito-Code lautet wie folgt. Beachten Sie, dass dies eine sehr grobe Beschreibung ist - hier sind viele Details im Spiel. Ich schlage vor, dass Sie die Quelle auf Github selbst überprüfen .
Wenn Sie eine Klasse mit der mock
Methode der Mockito
Klasse verspotten , geschieht im Wesentlichen Folgendes:
Mockito.mock
delegiert an org.mockito.internal.MockitoCore
.mock und übergibt die Standard-Mock-Einstellungen als Parameter.
MockitoCore.mock
delegiert an org.mockito.internal.util.MockUtil
.createMock
- Die
MockUtil
Klasse verwendet die ClassPathLoader
Klasse, um eine Instanz MockMaker
zum Erstellen des Mocks abzurufen. Standardmäßig wird die CgLibMockMaker- Klasse verwendet.
CgLibMockMaker
verwendet eine von JMock entliehene Klasse, ClassImposterizer
die das Erstellen des Mocks übernimmt. Die Schlüsselelemente der verwendeten 'Mockito-Magie' sind die MethodInterceptor
zum Erstellen des Mocks verwendeten: der Mockito MethodInterceptorFilter
und eine Kette von MockHandler-Instanzen, einschließlich einer Instanz von MockHandlerImpl . Der Methoden-Interceptor übergibt Aufrufe an die MockHandlerImpl-Instanz, die die Geschäftslogik implementiert, die angewendet werden soll, wenn eine Methode für einen Mock aufgerufen wird (dh sucht, ob bereits eine Antwort aufgezeichnet wurde, und ermittelt, ob der Aufruf einen neuen Stub darstellt usw.). Der Standardstatus ist, dass ein typgerechter leerer Wert zurückgegeben wird, wenn für die aufgerufene Methode noch kein Stub registriert ist.
Schauen wir uns nun den Code in Ihrem Beispiel an:
when(mock.method()).thenReturn(someValue)
Hier ist die Reihenfolge, in der dieser Code ausgeführt wird:
mock.method()
when(<result of step 1>)
<result of step 2>.thenReturn
Der Schlüssel zum Verständnis der Vorgänge liegt darin, was passiert, wenn die Methode auf dem Mock aufgerufen wird: Dem Methodenabfangjäger werden Informationen über den Methodenaufruf übergeben und an seine MockHandler
Instanzkette delegiert, an die schließlich delegiert wird MockHandlerImpl#handle
. Währenddessen erstellt MockHandlerImpl#handle
der Mock-Handler eine Instanz von OngoingStubbingImpl
und übergibt sie an die gemeinsam genutzte MockingProgress
Instanz.
Wenn die when
Methode nach dem Aufruf von aufgerufen wird method()
, delegiert sie an MockitoCore.when
, wodurch die stub()
Methode derselben Klasse aufgerufen wird . Diese Methode entpackt das laufende Stubbing aus der gemeinsam genutzten MockingProgress
Instanz, in die der verspottete method()
Aufruf geschrieben hat, und gibt es zurück. Dann wird die thenReturn
Methode für die OngoingStubbing
Instanz aufgerufen .