Mockito.any () übergeben Schnittstelle mit Generika

168

Ist es möglich, den Typ einer Schnittstelle mit Generika zu übergeben?

Die Schnittstelle:

public interface AsyncCallback<T>

In meiner Testmethode:

Mockito.any(AsyncCallback.class)

Putting <ResponseX>hinter oder .classfunktioniert nicht.

lrxw
quelle

Antworten:

304

Es gibt einen typsicheren Weg: Verwenden ArgumentMatchers.any()und qualifizieren Sie ihn mit dem Typ:

ArgumentMatchers.<AsyncCallback<ResponseX>>any()
thSoft
quelle
4
Ich bestätige, dass diese Antwort funktioniert und die Warnung korrekt unterdrückt.
Kevinarpe
1
Dies ist nicht wirklich sicherer, da die eigentliche Methode sowieso nur mit dem korrekt eingegebenen Argument aufgerufen werden kann. Es war nur notwendig, den Pre-Java8-Compiler zu befriedigen, dem diese Art von Typinferenz fehlte.
Hermann
Ich habe so etwas wie diese verwendet. ResponseEntity <List <Map <String, Object >>> responseEntity = Matchers. <ResponseEntity <List <Map <String, Object >>>> any (); Und es gibt immer null zurück
Arun
6
Mit neuen Versionen von Mockito:(Matchers.<AsyncCallback<ResponseX>>any()
pierrefevrier
15
Matchersist eigentlich veraltet, hat aber ArgumentMatchersfunktioniert.
Guijob
67

Mit Java 8 können Sie any()aufgrund der erweiterten Typinferenz einfach (unter der Annahme eines statischen Imports) ohne Argument oder Typparameter verwenden. Der Compiler weiß jetzt aus dem Zieltyp (dem Typ des Methodenarguments), dass Sie tatsächlich meinen Matchers.<AsyncCallback<ResponseX>>any(), was die Lösung vor Java 8 ist.

ihr Mann
quelle
Würde nicht so gut any()passen AsyncCallback<AnyOtherType>?
Matthew Read
@MatthewRead Using AsyncCallback<AnyOtherType>sollte nicht einmal kompiliert werden, wenn der Argumenttyp 'AsyncCallback <ResponseX>' ist.
Hermann
1
Ich wundere mich über eine Situation, in der der Argumenttyp ebenfalls generisch ist, Sie ihn jedoch nur für einen konkreten Typ verspotten möchten (oder für mehrere Typen auf unterschiedliche Weise verspotten möchten). In Anbetracht when(x.y(any())).thenAnswer(...)zum Beispiel, wo yist public <T> T y(AsyncCallback<T> arg). Vielleicht ist es besser, den Typ in der Antwort zu überprüfen, wenn dies erforderlich ist?
Matthew Read
2
@MatthewRead Aufgrund des Löschens kann der tatsächliche Typ zur Laufzeit von Mockito nicht überprüft werden. Sie können also nicht einmal verwenden isA(). Wenn das Objekt a enthältClass Objekt enthält, das dem Typ entspricht, und die Schnittstelle dies verfügbar macht, können Sie es wahrscheinlich in einem benutzerdefinierten Matcher überprüfen. Oder Sie können beispielsweise im Fall von a Collectionden Typ der Elemente überprüfen.
Hermann
1
Matchers wurde ersetzt durch ArgumentMatchers in Mockito v2
bheussler
15

Ich musste den folgenden Mechamismus anwenden, um Generika zuzulassen:

import static org.mockito.Matchers.any;
List<String> list = any();
when(callMyMethod.getResult(list)).thenReturn(myResultString);

Hoffe das hilft jemandem.

theINtoy
quelle
3
Siehe meine Antwort: Dies ist mit Java 8 nicht mehr erforderlich.
Hermann
5

Pierrefevrier-Kommentar als Antwort posten, was nützlich sein kann, wenn er in einer Antwort anstelle von Kommentaren enthalten ist.

Mit neuen Versionen von Mockito: (Matchers.<AsyncCallback<ResponseX>>any()

durchhängen
quelle
1
Ich habe seinen Kommentar zur ursprünglichen Antwort hinzugefügt
Joergi
2

Nach der Antwort von thSoft bedeutete das Setzen des qualifizierten Aufrufs einer beliebigen Methode () in der Methode, dass ich die Qualifikation entfernen konnte, da der Rückgabetyp Rückschlüsse zuließ:

private HashMap<String, String> anyStringStringHashMap() {
    return Matchers.any();
}
JWGS
quelle
0

Sie können es einfach umsetzen und Unterdrückungswarnungen hinzufügen, wenn Sie möchten:

@SuppressWarnings("unchecked")    
AsyncCallback<ResponseX> callback = Mockito.any(AsyncCallback.class)

Wenn Java 'generische' Generika zulässt, könnten sie eine Methode wie diese haben, nach der Sie suchen

private static <T, E> T<E> mock(Class<T<E>> clazz)
Garrett Hall
quelle
Als ich dies versuchte, erhielt ich einen Fehler in meinem Test:You cannot use argument matchers outside of verification or stubbing.
Kevinarpe
Keine gute Idee @SuppressWarnings: Pre-Java 8, wenn Sie es einer separaten Variablen zuweisen any()möchten , können Sie es wie in der Antwort von INToy verwenden. Jetzt mit Java 8, any()kann inline verwendet werden, ohne dass eine separate Zuordnung erforderlich ist.
Hermann
@kevinarpe Wenn Sie mehrere Argument-Matcher haben, müssen diese in der von der Java-Sprache angegebenen Reihenfolge aufgerufen werden.
TWiStErRob
0

Ich hatte ein ähnliches Problem mit Spring Example:

Mockito.when(repo.findAll(Mockito.<Example<SrvReqToSupplierComment>>any()))
            .thenReturn(Lists.emptyList());

Hier müssen Sie die Qualifikation verwenden. Die Methode b / c findAll kann mehrere Typen annehmen, z. B. Sortund Iterable. Sie können Mockito.any(Example.class)natürlich auch die Typensicherheitswarnung verwenden.

gagarwa
quelle