Gibt es eine Möglichkeit, mit einem Klassenargument der folgenden Beispielroutine übereinzustimmen?
class A {
public B method(Class<? extends A> a) {}
}
Wie kann ich immer eine zurückgeben, new B()
unabhängig davon, an welche Klasse übergeben wird method
? Der folgende Versuch funktioniert nur für den speziellen Fall, in dem A
eine Übereinstimmung vorliegt.
A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);
EDIT : Eine Lösung ist
(Class<?>) any(Class.class)
Class<?>
tolle!Antworten:
Zwei weitere Möglichkeiten (siehe meinen Kommentar zur vorherigen Antwort von @Tomasz Nurkiewicz):
Der erste beruht auf der Tatsache, dass der Compiler Sie einfach nicht zulässt, dass etwas vom falschen Typ übergeben wird:
Sie verlieren die genaue Eingabe (die
Class<? extends A>
), aber es funktioniert wahrscheinlich so, wie Sie es brauchen.Die zweite ist viel komplizierter, aber wahrscheinlich eine bessere Lösung, wenn Sie wirklich sicher sein möchten, dass das Argument
method()
eineA
oder eine Unterklasse vonA
:Wo
ClassOrSubclassMatcher
ist einorg.hamcrest.BaseMatcher
definiert als:Puh! Ich würde mit der ersten Option gehen, bis Sie wirklich eine genauere Kontrolle darüber bekommen müssen, was
method()
tatsächlich zurückkommt :-)quelle
if (obj instanceof Class)
bringt die Dinge für mich durcheinander, also habe ich es entfernt.extends BaseMatcher<Class<T>>
zu just wechselnextends BaseMatcher<T>
. Nur zu Ihrer Information, wenn jemand andere Kompilierungsfehler bekommt, probieren Sie das aus.matches
Funktion auf die folgenden:public boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }
Es gibt einen anderen Weg, dies ohne Besetzung zu tun:
Diese Lösung zwingt die Methode
any()
, denClass<A>
Typ und nicht den Standardwert (Object
) zurückzugeben.quelle
Matchers
ist in neueren Versionen von Mockito veraltet und wird wahrscheinlich in Version 3.0 entfernt. Verwenden SieArgumentMatchers
stattdessen:when(a.method(ArgumentMatchers.<Class<A>>any())).thenReturn(b);
Wenn Sie keine Ahnung haben, welches Paket Sie importieren müssen:
ODER
quelle
org.mockito.ArgumentMatchers.any
Wie wäre es mit:
oder:
quelle
method(A a)
- aber es ist (effektiv)method(Class<A> a)
- wäre, also müssten Sie verwenden:when(a.method(isA(Class.class))).thenReturn(b);
oderwhen(a.method((Class<A>) notNull())).thenReturn(b);
Die Lösung von Millhouse funktioniert mit der neuesten Version von Mockito nicht mehr
Diese Lösung funktioniert mit Java 8 und Mockito 2.2.9
wo
ArgumentMatcher
ist eine Instanz vonorg.mockito.ArgumentMatcher
Und die Verwendung
quelle
public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }