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);
ИЗМЕНИТЬ: одно решение -
(Class<?>) any(Class.class)
Ответы
Ответ 1
Еще два способа сделать это (см. мой комментарий к предыдущему ответу @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()
действительно возвращает: -)
Ответ 2
Есть другой способ сделать это без приведения:
when(a.method(Matchers.<Class<A>>any())).thenReturn(b);
Это решение заставляет метод any()
возвращать тип Class<A>
, а не его значение по умолчанию (Object
).
Ответ 3
Если вы не знаете, какой пакет вам нужно импортировать:
import static org.mockito.Matchers.any;
any(SomeClass.class)
ИЛИ
import org.mockito.Matchers;
Matchers.any(SomeClass.class)
Ответ 4
Как насчет:
when(a.method(isA(A.class))).thenReturn(b);
или
when(a.method((A)notNull())).thenReturn(b);
Ответ 5
решение от мельницы больше не работает с последней версией mockito
Это решение работает с java 8 и mockito 2.2.9
где ArgumentMatcher
является экземпляром org.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);