Gibt es eine Möglichkeit, eine Liste eines bestimmten Typs mit mockitos ArgumentCaptore zu erfassen? Das funktioniert nicht:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
java
unit-testing
junit
mockito
Andreas Köberle
quelle
quelle
ArrayList
). Sie können immerList
Schnittstelle verwenden, und wenn Sie die Tatsache darstellen möchten, dass es kovariant ist, dann können Sie verwendenextends
:ArgumentCaptor<? extends List<SomeType>>
Antworten:
Das verschachtelte Generika-Problem kann mit der Annotation @Captor vermieden werden :
quelle
MockitoAnnotations.initMocks(this)
in der@Before
Methode, anstatt einen Läufer zu verwenden, der die Möglichkeit ausschließt, einen anderen Läufer zu verwenden. +1, danke, dass Sie auf die Anmerkung hingewiesen haben.Ja, dies ist ein allgemeines Generika-Problem, nicht mockito-spezifisch.
Es gibt kein Klassenobjekt für
ArrayList<SomeType>
, und daher können Sie ein solches Objekt nicht typsicher an eine Methode übergeben, für die a erforderlich istClass<ArrayList<SomeType>>
.Sie können das Objekt in den richtigen Typ umwandeln:
Dies gibt einige Warnungen vor unsicheren Casts aus, und natürlich kann Ihr ArgumentCaptor nicht wirklich zwischen
ArrayList<SomeType>
und unterscheiden,ArrayList<AnotherType>
ohne die Elemente zu überprüfen.(Wie in der anderen Antwort erwähnt, gibt es zwar ein allgemeines generisches Problem, es gibt jedoch eine Mockito-spezifische Lösung für das Typensicherheitsproblem mit der
@Captor
Anmerkung. Es kann immer noch nicht zwischen einemArrayList<SomeType>
und einem unterschieden werdenArrayList<OtherType>
.)Bearbeiten:
Schauen Sie sich auch Tenshis Kommentar an. Sie können den Originalcode von Paŭlo Ebermann in diesen ändern (viel einfacher).
quelle
ArgumentCaptor<List<SimeType>> argument = ArgumentCaptor.forClass((Class) List.class);
@SuppressWarnings("unchecked")
. Außerdem ist das Casting inClass
überflüssig.Class
ist in meinen Tests nicht überflüssig.Wenn Sie keine Angst vor der alten Java-Semantik (nicht typsichere generische Semantik) haben, funktioniert dies auch und ist einigermaßen einfach:
quelle
quelle
Basierend auf den Kommentaren von @ tenshi und @ pkalinow (auch ein großes Lob an @rogerdpack) ist das Folgende eine einfache Lösung zum Erstellen eines Listenargument-Captors, der auch die Warnung "Verwendet nicht aktivierte oder unsichere Operationen" deaktiviert :
Vollständiges Beispiel hier und entsprechender CI-Build und Testlauf hier .
Unser Team verwendet dies seit einiger Zeit in unseren Unit-Tests und dies scheint die einfachste Lösung für uns zu sein.
quelle
Für eine frühere Version von junit können Sie dies tun
quelle
Ich hatte das gleiche Problem mit der Testaktivität in meiner Android-App. Ich habe benutzt
ActivityInstrumentationTestCase2
undMockitoAnnotations.initMocks(this);
nicht gearbeitet. Ich habe dieses Problem mit einer anderen Klasse mit jeweils Feld gelöst. Zum Beispiel:Dann in der Aktivitätstestmethode:
quelle
In Mockitos GitHub gibt es ein offenes Problem mit genau diesem Problem.
Ich habe eine einfache Problemumgehung gefunden, die Sie nicht zwingt, Anmerkungen in Ihren Tests zu verwenden:
Was hier passiert ist, dass wir eine neue Klasse mit der
@Captor
Annotation erstellen und den Captor in sie einfügen. Dann extrahieren wir einfach den Captor und geben ihn von unserer statischen Methode zurück.In Ihrem Test können Sie es so verwenden:
Oder mit einer Syntax, die der von Jackson ähnelt
TypeReference
:Es funktioniert, weil Mockito eigentlich keine Typinformationen benötigt (im Gegensatz zu Serialisierern zum Beispiel).
quelle