適切Mockitoで可変引数と一致する方法
-
26-09-2019 - |
質問
私はMockitoを使用して可変引数パラメータを持つメソッドを模擬するために取得しようとしてきます:
interface A {
B b(int x, int y, C... c);
}
A a = mock(A.class);
B b = mock(B.class);
when(a.b(anyInt(), anyInt(), any(C[].class))).thenReturn(b);
assertEquals(b, a.b(1, 2));
これは私が代わりにこれを行うがあれば、仕事をしていない。
when(a.b(anyInt(), anyInt())).thenReturn(b);
assertEquals(b, a.b(1, 2));
この作品、私は完全にメソッドをスタブ時に引数を可変引数ます。
が省略されていることにもかかわらず、任意の手がかり?
解決
Mockito 1.8.1は、<のhref = "https://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html#anyVararg%28%29" のrelを導入します= "noreferrer"> anyVararg()マッチャの
when(a.b(anyInt(), anyInt(), Matchers.<String>anyVararg())).thenReturn(b);
また、このために歴史を参照してください。 https://code.google.com/アーカイブ/ P / mockito /問題/ 62 の
編集新しい構文廃止後:
when(a.b(anyInt(), anyInt(), ArgumentMatchers.<String>any())).thenReturn(b);
他のヒント
A多少の文書化されていない機能:あなたはそれが正常に動作することがorg.mockito.internal.matchers.VarargMatcher
を実装持っている必要があります一致可変引数引数というカスタムのMatcherを開発する場合。それはあなたのMatcherを使用して可変引数を持つメソッドを呼び出すときにMockitoが正しく引数を比較しないであろうことなく、空のマーカーインターフェイス、です。
class MyVarargMatcher extends ArgumentMatcher<C[]> implements VarargMatcher {
@Override public boolean matches(Object varargArgument) {
return /* does it match? */ true;
}
}
when(a.b(anyInt(), anyInt(), argThat(new MyVarargMatcher()))).thenReturn(b);
ここイーライレヴィンの答えのビルがより一般的なソリューションです。
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.mockito.ArgumentMatcher;
import org.mockito.internal.matchers.VarargMatcher;
import static org.mockito.Matchers.argThat;
public class VarArgMatcher<T> extends ArgumentMatcher<T[]> implements VarargMatcher {
public static <T> T[] varArgThat(Matcher<T[]> hamcrestMatcher) {
argThat(new VarArgMatcher(hamcrestMatcher));
return null;
}
private final Matcher<T[]> hamcrestMatcher;
private VarArgMatcher(Matcher<T[]> hamcrestMatcher) {
this.hamcrestMatcher = hamcrestMatcher;
}
@Override
public boolean matches(Object o) {
return hamcrestMatcher.matches(o);
}
@Override
public void describeTo(Description description) {
description.appendText("has varargs: ").appendDescriptionOf(hamcrestMatcher);
}
}
次に、あなたは、このようにhamcrestの配列マッチャでそれを使用することができます:
verify(a).b(VarArgMatcher.varArgThat(
org.hamcrest.collection.IsArrayContaining.hasItemInArray("Test")));
(もちろん、静的な輸入は、これは読みやすくレンダリングされます。)
私はあなたが今、次のことを行うことができますがMockito 2.2.15とピーター・ウェストマコットの答えのコードを使用しています:
verify(a).method(100L, arg1, arg2, arg3)
arg1, arg2, arg3
は可変引数です。
topchefの回答を踏まえ、
私が代わりにMatchers.anyVararrgのMockito.anyVarargを使用する必要がありました2.0.31-βについては、
when(a.b(anyInt(), anyInt(), Mockito.<String>anyVararg())).thenReturn(b);
私の場合は、その引数をキャプチャすることをメソッドのシグネチャは、次のとおりです。
public byte[] write(byte ... data) throws IOException;
この場合は、をバイト配列を明示的にキャストする必要があります
when(spi.write((byte[])anyVararg())).thenReturn(someValue);
私はmockitoのバージョンを使用してい1.10.19
することもできます引数をループます:
Object[] args = invocation.getArguments();
for( int argNo = 0; argNo < args.length; ++argNo) {
// ... do something with args[argNo]
}
たとえば、リストまたは任意に追加し、その種類を確認し、それらを適切にキャストします。
@topchefから答えを適応、
Mockito.when(a.b(Mockito.anyInt(), Mockito.anyInt(), Mockito.any())).thenReturn(b);
Mockito 2.23.4用のJavaドキュメントごとに、Mockito.any()は、 "ヌルを含め、何もマッチし、可変引数。"
あなたはArgumentCaptorキャプチャを渡した後、「getAllValues」を使用して、リストとして可変引数取得することによって、これを達成することができ、次を参照してください。ます。https:/ /stackoverflow.com/a/55621731/11342928する