mockitoコールバックと引数値の取得


88

Mockitoに関数の引数値をキャプチャさせる運がありません!私は検索エンジンのインデックスをモックしていて、インデックスを作成する代わりに、ハッシュを使用しています。

// Fake index for solr
Hashmap<Integer,Document> fakeIndex;

// Add a document 666 to the fakeIndex
SolrIndexReader reader = Mockito.mock(SolrIndexReader.class);

// Give the reader access to the fake index
Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))

クエリの結果(つまり、クエリが返すドキュメント)をテストしているため、任意の引数を使用することはできません。同様に、ドキュメントごとに特定の値を指定したり、行を設定したりしたくありません。

Mockito.when(reader.document(0)).thenReturn(document(fakeIndex(0))
Mockito.when(reader.document(1)).thenReturn(document(fakeIndex(1))
....
Mockito.when(reader.document(n)).thenReturn(document(fakeIndex(n))

Mockito使用」ページの「コールバック」セクションを見ました。残念ながら、それはJavaではなく、Javaで機能するように自分で解釈することはできませんでした。

編集(説明のため):Mockitoに引数Xをキャプチャさせて、それを関数に渡すにはどうすればよいですか?Xの正確な値(またはref)を関数に渡してほしい。

すべてのケースを列挙したくはありません。また、クエリごとに異なる結果をテストしているため、任意の引数は機能しません。

Mockitoページには

val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString } 

それはJavaではなく、Javaに変換する方法や、起こったことを関数に渡す方法がわかりません。


何があなたのために失敗しているのかを正確に理解しているのかわかりません。を呼び出すとMockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))、モックオブジェクトが設定されます。電話をかけるとどうなりますreader.document(666)か?
高度にカフェイン化された2011

666は正常に動作します。ただし、特定の数値Xを渡して、fakeIndex(X)の結果を取得できるようにしたいと思います。クエリをテストするための潜在的なドキュメントが多数ありますが、それらすべてを入力したくありません。
nflacco 2011

回答:


103

私はMockitoを使ったことがありませんが、学びたいので、ここに行きます。私よりも無知な人が答えた場合は、最初にその答えを試してください!

Mockito.when(reader.document(anyInt())).thenAnswer(new Answer() {
 public Object answer(InvocationOnMock invocation) {
     Object[] args = invocation.getArguments();
     Object mock = invocation.getMock();
     return document(fakeIndex((int)(Integer)args[0]));
     }
 });

2
Mockitoへの右側のリンクに気づきました:メソッドに渡された引数を返すようにする方法。私が近くにいるように見えます。
Ed Staub 2011

元の質問の相関関係に対する強力なユーザー評判(666)!それは非常にうまくいきました。だけ....私はスタッフコンパイルを取得するために作られたオブジェクトの回答(InvocationOnMock呼び出し)の前に、公開を入れた変更
nflacco

54

ArgumentCaptorsを確認してください。

https://site.mockito.org/javadoc/current/org/mockito/ArgumentCaptor.html

ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
Mockito.when(reader.document(argument.capture())).thenAnswer(
  new Answer() {
    Object answer(InvocationOnMock invocation) {
      return document(argument.getValue());
    }
  });

3
うわー、ArgumentCaptorスタブにsを使用できるとは知りませんでした。しかし、そのリンクにはそれについての大きな古い警告があります。注意して続行してください。
無実の2015

3
はい、その通りです。キャプターは、検証でのみ使用する必要があります。
qualidafial 2016

41

verify()をArgumentCaptorと組み合わせて使用​​してテストでの実行を保証し、ArgumentCaptorを使用して引数を評価することをお勧めします。

ArgumentCaptor<Document> argument = ArgumentCaptor.forClass(Document.class);
verify(reader).document(argument.capture());
assertEquals(*expected value here*, argument.getValue());

引数の値は、argument.getValue()を介して明らかにアクセス可能であり、さらに操作/チェックするなど、やりたいことは何でもできます。


2
ベストアンサー:わかりやすく、わかりやすい
RaduCugut19年

質問には答えません。質問はMockito.whenについてであり、確認しません。
seBaka28

@ seBaka28引数を取得するための最良の解決策は、引数キャプターです。ArgumentCaptorsは、Mockitoの作成者による検証とともに使用することを強くお勧めします。したがって、完全な視点で回答したいと思います。あなた自身がそれらを使用しないことを選択した場合、それはあなたの選択ですが、お勧めできません。編集:これがどのように反対票を正当化するのかわかりませんが、それはあなたの選択でもあります。
fl0w

1
質問に答えないからです。はい、ArgumentCaptorは引数をキャプチャする場合に最適ですが、OPが実行しようとしているwhen(...)。thenReturn()と組み合わせて使用​​することはできません。特定のパラメーターに基づいて、モックサービス特定のオブジェクトを返すことになっています。
seBaka28

1
@YuraHoyは、verifyを使用し、オブジェクトまたはメソッドがverifyに期待するよりも頻繁に呼び出される場合の標準エラーメッセージです。次のようにtimes(n)引数を追加することで、期待カウントを変更できます。verify(reader、times(5))-これは5つの相互作用を期待します。参考のために参照してください:baeldung.com/mockito-verify
fl0w

13

Java 8では、これは次のようになります。

Mockito.when(reader.document(anyInt())).thenAnswer(
  (InvocationOnMock invocation) -> document(invocation.getArguments()[0]));

それdocumentは地図だと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.