Mockito соответствует любому аргументу класса
есть ли способ сопоставить любой аргумент класса из приведенного ниже примера процедуры?
class A {
public B method(Class<? extends A> a) {}
}
как я могу всегда возвратить new B()
независимо от того, какой класс перешла в method
? Следующая попытка работает только для конкретного случая, когда A
сочетается.
A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);
EDIT: одним из решений является
(Class<?>) any(Class.class)
5 ответов:
еще два способа сделать это (см. Мой комментарий к предыдущему ответу @Tomasz Nurkiewicz):
первый опирается на то, что компилятор просто не позволит вам передать что-то не того типа:
when(a.method(any(Class.class))).thenReturn(b);
вы теряете точную типизацию (
Class<? extends A>
) но он, вероятно, работает так, как вам нужно.второй гораздо более вовлечен, но, возможно, лучшее решение, если вы действительно хочу быть уверен, что аргумент
method()
этоA
или подклассA
:when(a.method(Matchers.argThat(new ClassOrSubclassMatcher<A>(A.class)))).thenReturn(b);
здесь
ClassOrSubclassMatcher
этоorg.hamcrest.BaseMatcher
определено как:public class ClassOrSubclassMatcher<T> extends BaseMatcher<Class<T>> { private final Class<T> targetClass; public ClassOrSubclassMatcher(Class<T> targetClass) { this.targetClass = targetClass; } @SuppressWarnings("unchecked") public boolean matches(Object obj) { if (obj != null) { if (obj instanceof Class) { return targetClass.isAssignableFrom((Class<T>) obj); } } return false; } public void describeTo(Description desc) { desc.appendText("Matches a class or subclass"); } }
Фух! Я бы пошел с первым вариантом, пока вы действительно нужно получить более точный контроль над тем, что
method()
на самом деле возвращается :-)
есть еще один способ сделать это, не бросил:
when(a.method(Matchers.<Class<A>>any())).thenReturn(b);
это решение заставляет способ
any()
вернутьсяClass<A>
тип, а не значение по умолчанию (Object
).
Если вы не знаете, какой пакет вам нужно импортировать:
import static org.mockito.Matchers.any; any(SomeClass.class)
или
import org.mockito.Matchers; Matchers.any(SomeClass.class)
Как насчет:
when(a.method(isA(A.class))).thenReturn(b);
или:
when(a.method((A)notNull())).thenReturn(b);
решение от millhouse больше не работает с последней версией mockito
это решение работает с java 8 и mockito 2.2.9
здесь
ArgumentMatcher
- это instanceoforg.mockito.ArgumentMatcher
public class ClassOrSubclassMatcher<T> implements ArgumentMatcher<Class<T>> { private final Class<T> targetClass; public ClassOrSubclassMatcher(Class<T> targetClass) { this.targetClass = targetClass; } @Override public boolean matches(Class<T> obj) { if (obj != null) { if (obj instanceof Class) { return targetClass.isAssignableFrom( obj); } } return false; } }
и использовать
when(a.method(ArgumentMatchers.argThat(new ClassOrSubclassMatcher<>(A.class)))).thenReturn(b);