173

私はMockitoを使用してvarargパラメーターでメソッドをモックしようとしています:

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

メソッドをスタブ化するときにvarargs引数を完全に省略したにもかかわらず、これは機能します。

手がかりはありますか?

4

11 に答える 11

261

Mockito 1.8.1はanyVararg()マッチャーを導入しました:

when(a.b(anyInt(), anyInt(), Matchers.<String>anyVararg())).thenReturn(b);

この履歴も参照してください:https ://code.google.com/archive/p/mockito/issues/62

非推奨の後に新しい構文を編集します。

when(a.b(anyInt(), anyInt(), ArgumentMatchers.<String>any())).thenReturn(b);
于 2010-04-14T02:53:21.963 に答える
32

やや文書化されていない機能:vararg引数に一致するカスタムマッチャーを開発する場合は、org.mockito.internal.matchers.VarargMatcher正しく機能するように実装する必要があります。これは空のマーカーインターフェイスであり、これがないと、MockitoはMatcherを使用してvarargsを使用してメソッドを呼び出すときに引数を正しく比較しません。

例えば:

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);
于 2011-11-03T00:15:02.410 に答える
9

ここでのEliLevineの答えに基づいて構築することは、より一般的な解決策です。

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

(明らかに、静的インポートはこれをより読みやすくします。)

于 2015-06-30T15:40:21.053 に答える
3

私はPeterWestmacottの回答のコードを使用してきましたが、Mockito 2.2.15を使用すると、次のことができるようになります。

verify(a).method(100L, arg1, arg2, arg3)

arg1, arg2, arg3varargsはどこにありますか。

于 2016-11-14T09:26:08.733 に答える
2

トプシェフの答えに基づいて、

2.0.31ベータ版では、Matchers.anyVararrgの代わりにMockito.anyVarargを使用する必要がありました。

when(a.b(anyInt(), anyInt(), Mockito.<String>anyVararg())).thenReturn(b);
于 2016-04-29T17:44:37.643 に答える
0

私の場合、引数を取得したいメソッドのシグネチャは次のとおりです。

    public byte[] write(byte ... data) throws IOException;

この場合、バイト配列に明示的にキャストする必要があります。

       when(spi.write((byte[])anyVararg())).thenReturn(someValue);

mockitoバージョンを使用しています1.10.19

于 2016-05-03T18:31:32.883 に答える
0

引数をループすることもできます。

Object[] args = invocation.getArguments(); 
for( int argNo = 0; argNo < args.length; ++argNo) { 
    // ... do something with args[argNo] 
}

たとえば、タイプを確認して適切にキャストしたり、リストに追加したりします。

于 2017-02-10T12:20:44.623 に答える
0

@topchefからの回答を採用して、

Mockito.when(a.b(Mockito.anyInt(), Mockito.anyInt(), Mockito.any())).thenReturn(b);

Mockito 2.23.4のJavaドキュメントによると、Mockito.any()は「nullやvarargsを含むすべてのものに一致します。」

于 2019-01-25T14:42:19.200 に答える
0

これを実現するには、ArgumentCaptorキャプチャを渡し、「getAllValues」を使用してvarargsをリストとして取得します。https ://stackoverflow.com/a/55621731/11342928を参照してください。

于 2019-04-10T21:47:34.647 に答える
0

他の答えは理にかなっており、テストが明らかに機能するので、メソッドがvarargを受け取らなかったかのようにテストすることをお勧めしますが、代わりに通常の明確に定義されたパラメーターを取ります。これは、SLF4J-loggerのように、あいまいな可能性のあるパラメーターに関連してオーバーライドされたメソッドが配置されている状況で役立ちます。

テストする:

jobLogger.info("{} finished: {} tasks processed with {} failures, took {}", jobName, count, errors, duration);

これにはたくさんのオーバーライドがあり、重要なメソッドはそのように宣言されています

Logger.info(String, Object...)

検証:

verify(loggerMock).info(anyString(), anyString(), anyInt(), anyInt(), anyString());

errors上記が整数であり、長くないように機能することを証明するため、以下は実行されません。

verify(loggerMock).info(anyString(), anyString(), anyInt(), anyLong(), anyString());

when()したがって、-stuffの代わりに簡単に使用verify()して、必要な戻り値を設定できます。

そして、それはおそらくより多くの意図を示し、より読みやすくなっています。ここではキャプチャも使用でき、この方法ではるかに簡単にアクセスできます。

Mockito2.15でテスト済み

于 2021-06-14T07:22:43.390 に答える
0

varargsパラメーターとして渡される配列argを照合するには、any(Class type)メソッドを使用する必要がありました。

ArgumentMatchers.any(クラスタイプ)

実装のコードはvarargに対応しています。

reportMatcher(new InstanceOf.VarArgAware(

String[]argをString...paramに一致させる私の場合、以下が機能しました:-

any(String.class)
于 2021-08-24T12:19:30.517 に答える