以下のサンプルルーチンのクラス引数に一致する方法はありますか?
class A {
public B method(Class<? extends A> a) {}
}
どのようにしてmethod
に渡されるクラスに関係なくalwaysnew B()
を返すことができますか?次の試行は、A
が一致する特定の場合にのみ機能します。
A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);
EDIT:1つのソリューションは
(Class<?>) any(Class.class)
それを行うには、さらに2つの方法があります(@Tomasz Nurkiewiczによる以前の回答に関する私のコメントを参照)。
最初は、コンパイラが間違ったタイプのものを渡さないようにするという事実に依存しています。
when(a.method(any(Class.class))).thenReturn(b);
正確なタイピング(Class<? extends A>
)は失われますが、おそらく必要に応じて機能します。
2番目の方法はより複雑ですが、実際に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");
}
}
ふう! reallymethod()
が実際に返すものをより細かく制御する必要があるまで、最初のオプションを使用します:-)
キャストせずにそれを行う別の方法があります。
when(a.method(Matchers.<Class<A>>any())).thenReturn(b);
このソリューションは、メソッドany()
がデフォルト値(Object
)ではなくClass<A>
タイプを返すように強制します。
インポートする必要のあるパッケージがわからない場合:
import static org.mockito.Matchers.any;
any(SomeClass.class)
OR
import org.mockito.Matchers;
Matchers.any(SomeClass.class)
どうですか:
when(a.method(isA(A.class))).thenReturn(b);
または:
when(a.method((A)notNull())).thenReturn(b);
ミルハウスのソリューションは、モッキートの最新バージョンではもう機能していません
このソリューションは、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);