Ich benutze Mockito 1.9.0. Ich möchte das Verhalten für eine einzelne Methode einer Klasse in einem JUnit-Test verspotten, also habe ich
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
Das Problem ist, dass in der zweiten Zeile myClassSpy.method1()
tatsächlich aufgerufen wird, was zu einer Ausnahme führt. Der einzige Grund, warum ich Mocks verwende, ist, dass später, wann myClassSpy.method1()
immer aufgerufen wird, die reale Methode nicht aufgerufen wird und das myResults
Objekt zurückgegeben wird.
MyClass
ist eine Schnittstelle und myInstance
ist eine Implementierung davon, wenn das wichtig ist.
Was muss ich tun, um dieses Spionageverhalten zu korrigieren?
Antworten:
Lassen Sie mich die offizielle Dokumentation zitieren :
In Ihrem Fall geht es ungefähr so:
quelle
send
Methode wird aufgerufenMein Fall war anders als die akzeptierte Antwort. Ich habe versucht, eine paketprivate Methode für eine Instanz zu verspotten, die nicht in diesem Paket enthalten war
und die Testklassen
Die Kompilierung ist korrekt, aber wenn versucht wird, den Test einzurichten, wird stattdessen die reale Methode aufgerufen.
Das Deklarieren der Methode als geschützt oder öffentlich behebt das Problem, obwohl es keine saubere Lösung ist.
quelle
In meinem Fall musste ich mit Mockito 2.0 alle
any()
Parameter auf ändern ,nullable()
um den eigentlichen Aufruf zu stoppen.quelle
foo = Mockito.spy(foo);
Mockito.doReturn(someValue).when(foo).methodToPrevent(nullable(ArgumentType.class));
any
undeq
Matchern.Die Antwort von Tomasz Nurkiewicz scheint nicht die ganze Geschichte zu erzählen!
NB Mockito-Version: 1.10.19.
Ich bin ein Mockito-Neuling und kann daher das folgende Verhalten nicht erklären: Wenn es einen Experten gibt, der diese Antwort verbessern kann, fühlen Sie sich bitte frei.
Die hier fragliche Methode
getContentStringValue
ist NICHTfinal
und NICHTstatic
.Diese Linie hat die ursprüngliche Methode aufrufen
getContentStringValue
:Diese Zeile ruft nicht die ursprüngliche Methode auf
getContentStringValue
:Aus Gründen, die ich nicht beantworten kann,
isA()
führt die Verwendung dazu , dass das beabsichtigte (?) Verhalten "Methode nicht aufrufen"doReturn
fehlschlägt.Schauen wir uns die hier beteiligten Methodensignaturen an: Sie sind beide
static
Methoden vonMatchers
. Beide werden vom Javadoc zur Rückkehr aufgefordertnull
, was ein wenig schwierig ist, den Kopf in sich selbst zu bekommen. VermutlichClass
wird das als Parameter übergebene Objekt untersucht, das Ergebnis jedoch nie berechnet oder verworfen. Danull
dies für jede Klasse stehen kann und Sie hoffen, dass die verspottete Methode nicht aufgerufen wird, könnten die Signaturen vonisA( ... )
und nichtany( ... )
nurnull
einen generischen Parameter * zurückgeben<T>
?Wie auch immer:
Die API-Dokumentation gibt keinen Hinweis darauf. Es scheint auch zu sagen, dass die Notwendigkeit eines solchen Verhaltens "Methode nicht aufrufen" "sehr selten" ist. Persönlich verwende ich diese Technik die ganze Zeit : Normalerweise stelle ich fest, dass das Verspotten einige Zeilen umfasst, die "die Szene setzen" ... gefolgt vom Aufrufen einer Methode, die dann die Szene in dem von Ihnen inszenierten Scheinkontext "ausspielt". . und während Sie die Szenerie und die Requisiten einrichten, ist das Letzte, was Sie wollen, dass die Schauspieler die Bühne links betreten und anfangen, ihre Herzen zu spielen ...
Aber das geht weit über meine Gehaltsstufe hinaus ... Ich lade alle vorbeikommenden Mockito-Hohepriester zu Erklärungen ein ...
* Ist "generischer Parameter" der richtige Begriff?
quelle
Ein weiteres mögliches Szenario, das Probleme mit Spionen verursachen kann, ist das Testen von Spring Beans (mit Spring Test Framework) oder eines anderen Frameworks, das Ihre Objekte während des Tests als Proxy verwendet .
Beispiel
Im obigen Code versuchen sowohl Spring als auch Mockito, Ihr MonitoringDocumentsRepository-Objekt zu vertreten, aber Spring ist das erste, was einen echten Aufruf der findMonitoringDocuments-Methode verursacht. Wenn wir unseren Code direkt nach dem Aussetzen eines Spions auf ein Repository-Objekt debuggen, sieht es im Debugger folgendermaßen aus:
@SpyBean zur Rettung
Wenn
@Autowired
wir stattdessen eine Annotation verwenden@SpyBean
, lösen wir das obige Problem. Die SpyBean-Annotation fügt auch ein Repository-Objekt ein, wird jedoch zuerst von Mockito als Proxy verwendet und sieht im Debugger so ausund hier ist der Code:
quelle
Ich habe noch einen weiteren Grund für Spion gefunden, die ursprüngliche Methode aufzurufen.
Jemand hatte die Idee, eine
final
Klasse zu verspotten , und fand herausMockMaker
:Quelle: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
Nachdem ich diese Datei zusammengeführt und auf meinen Computer gebracht hatte, schlugen meine Tests fehl.
Ich musste nur die Zeile (oder die Datei) entfernen und
spy()
arbeitete.quelle
Etwas spät zur Party, aber die oben genannten Lösungen haben bei mir nicht funktioniert, also teile ich meine 0,02 $
Mokcito-Version: 1.10.19
MyClass.java
Test.java
Folgendes hat bei mir NICHT funktioniert (die eigentliche Methode wurde aufgerufen):
1.
2.
3.
Folgende ARBEITEN:
quelle
Eine Möglichkeit, um sicherzustellen, dass eine Methode aus einer Klasse nicht aufgerufen wird, besteht darin, die Methode mit einem Dummy zu überschreiben.
quelle
Antwort für Scala-Benutzer: Selbst das
doReturn
erste Mal funktioniert nicht! Siehe diesen Beitrag .quelle