Mockitoは任意のクラス引数と一致します


153

以下のサンプルルーチンのクラス引数を照合する方法はありますか?

class A {
     public B method(Class<? extends A> a) {}
}

どのクラスが渡されたかに関係なく、どのようにして常に返すことができますか?次の試みは、が一致する特定のケースでのみ機能します。new B()methodA

A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);

編集:1つの解決策は

(Class<?>) any(Class.class)

6
Class<?>すごい!
Antónioのアルメイダ

あなたの(Class <?>)any(Class.class)ソリューションがここでの答えになるはずです。私はむしろそれを以下に見られるClassOrSubclassMatcherクラスを使用したいです。
superbAfterSemperPhi

@superbAfterSemperPhiとjohan-sjöbergキャストを行わずに、別の方法で投稿しました。私はそれがより良い方法かもしれないと信じています。どう思いますか?
anmaia

回答:


188

それを行うための2つの方法(@Tomasz Nurkiewiczによる以前の回答に関する私のコメントを参照):

1つ目は、コンパイラーが間違った型のデータを渡せないという事実に依存しています。

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");
    }       
}

ふew!あなたがするまで、私は最初のオプションと一緒に行きたい、本当に何をより細かく制御を取得する必要がありmethod()、実際に戻ります:-)


if (obj instanceof Class)私のために台無しに物事は、私はそれを削除しました。
Daniel Smith、

クラスの宣言行で、私はextends BaseMatcher<Class<T>>ちょうどに変更する必要がありましたextends BaseMatcher<T>。参考までに、他の誰かがコンパイルエラーを受け取ったら、それを試してください。
ヤン

私も変更しなければならなかったmatches:以下の機能をpublic boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }

any(Class.class)がnullを返す-nullを返すのを避けるにはどうすればよいですか
Arvind Kumar

実際にmockitoからの「any」が多数あるため、インポートする必要があるクラスを実際に追加するとすばらしいでしょう
jpganz18

53

キャストなしでそれを行う別の方法があります:

when(a.method(Matchers.<Class<A>>any())).thenReturn(b);

このソリューションにより、メソッドはデフォルト値()ではなくタイプany()を返すClass<A>ようになりますObject


5
MatchersMockitoの新しいバージョンでは非推奨であり、バージョン3.0で削除される可能性があります。ArgumentMatchers代わりに使用:when(a.method(ArgumentMatchers.<Class<A>>any())).thenReturn(b);
Voicu

41

インポートする必要があるパッケージがわからない場合:

import static org.mockito.ArgumentMatchers.any;
any(SomeClass.class)

または

import org.mockito.ArgumentMatchers;
ArgumentMatchers.any(SomeClass.class)

13
これは私の命を救い、ハムクレストライブラリから誤って "any"をインポートしていました。
ガーボルナジ

3
今それは変更されましたorg.mockito.ArgumentMatchers.any
BOWS

27

どうですか:

when(a.method(isA(A.class))).thenReturn(b);

または:

when(a.method((A)notNull())).thenReturn(b);

4
これらは、メソッドシグネチャがmethod(A a)-(事実上)method(Class<A> a)-である場合にコンパイルおよび機能します。when(a.method(isA(Class.class))).thenReturn(b);when(a.method((Class<A>) notNull())).thenReturn(b);
したがって、

私にとっての第二部は魅力として機能します。any(SomeClass.class)との戦いは行き止まりにつながります。しかし、(SomeClass.class)notNull()は私の日を救いました
Vadim

同じ名前で引数が異なる2つのメソッドがある場合は、ここで2番目のバージョンを使用して、モックされるメソッドを明確にすることができます。最初のバージョンは私のためにそれをカットしませんでした(つまり、Java 8では)。
Patru

おかげで、isA(A.class)はうまく機能し、mvcConversionServiceは適切なクラスを選択します。これは、any(A.class)およびeq(A.class)では機能しませんでした。
d3rbastl3r

9

Millhouseのソリューションは、最近のバージョンのmockitoでは機能しなくなりました

このソリューションは、Java 8およびmockito 2.2.9で動作します

ArgumentMatcherinstanceofはどこですか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);

instanceof条件は不要になり、便利なメソッドを作成しました:public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }
Daniel Alder
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.