Czy istnieje sposób dopasowania dowolnego argumentu klasy w poniższej przykładowej procedurze?
class A {
public B method(Class<? extends A> a) {}
}
Jak zawsze mogę zwrócić, new B()
niezależnie od tego, do której klasy jest przekazywana method
? Poniższa próba działa tylko w konkretnym przypadku, w którym A
jest dopasowany.
A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);
EDYCJA : jednym rozwiązaniem jest
(Class<?>) any(Class.class)
Class<?>
niesamowity!Odpowiedzi:
Jeszcze dwa sposoby (zobacz mój komentarz do poprzedniej odpowiedzi autorstwa @Tomasz Nurkiewicz):
Pierwsza polega na tym, że kompilator po prostu nie pozwoli Ci przekazać czegoś niewłaściwego typu:
Tracisz dokładne wpisywanie (the
Class<? extends A>
), ale prawdopodobnie działa tak, jak tego potrzebujesz.Drugi jest o wiele bardziej skomplikowany, ale jest prawdopodobnie lepszym rozwiązaniem, jeśli naprawdę chcesz mieć pewność, że argument do
method()
jestA
podklasą lub podklasąA
:Gdzie
ClassOrSubclassMatcher
jestorg.hamcrest.BaseMatcher
zdefiniowany jako:Uff! Wybrałbym pierwszą opcję, dopóki naprawdę nie będziesz potrzebować dokładniejszej kontroli nad tym, co
method()
faktycznie zwraca :-)źródło
if (obj instanceof Class)
mes rzeczy dla mnie, więc usunąłem go.extends BaseMatcher<Class<T>>
na justextends BaseMatcher<T>
. Po prostu do Twojej wiadomości, jeśli ktoś inny dostanie błędy kompilacji, wypróbuj to.matches
funkcję na następującą:public boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }
Jest na to inny sposób bez obsady:
To rozwiązanie wymusza na metodzie
any()
zwracanieClass<A>
typu, a nie wartości domyślnej (Object
).źródło
Matchers
jest przestarzałe w nowszych wersjach Mockito i prawdopodobnie zostanie usunięte w wersji 3.0. UżyjArgumentMatchers
zamiast tego:when(a.method(ArgumentMatchers.<Class<A>>any())).thenReturn(b);
Jeśli nie masz pojęcia, który pakiet musisz zaimportować:
LUB
źródło
org.mockito.ArgumentMatchers.any
Co powiesz na:
lub:
źródło
method(A a)
- ale jest (efektywnie)method(Class<A> a)
- więc trzeba użyć:when(a.method(isA(Class.class))).thenReturn(b);
lubwhen(a.method((Class<A>) notNull())).thenReturn(b);
rozwiązanie od millhouse nie działa już z najnowszą wersją mockito
To rozwiązanie działa z Javą 8 i Mockito 2.2.9
gdzie
ArgumentMatcher
jest instancjaorg.mockito.ArgumentMatcher
I użycie
źródło
public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }