web-dev-qa-db-ja.com

スタブにArgumentCaptorを使用する方法は?

Mockitoでは documentation および javadocs と書かれています

ArgumentCaptorは検証で使用することをお勧めしますが、スタブでは使用しないことをお勧めします。

しかし、ArgumentCaptorがスタブにどのように使用できるかはわかりません。誰かが上記の声明を説明し、ArgumentCaptorをスタブに使用する方法を示したり、それを行う方法を示すリンクを提供したりできますか?

145
Can't Tell

テストするために次の方法を想定します。

public boolean doSomething(SomeClass arg);

Mockitoのドキュメントでは、notこの方法でcaptorを使用する必要があると書かれています。

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

スタブ処理中にマッチャーのみを使用できるため:

when(someObject.doSomething(eq(expected))).thenReturn(true);

しかし、検証は別の話です。テストでこのメソッドが特定の引数で呼び出されたことを確認する必要がある場合は、ArgumentCaptorを使用してください。

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));
251
Rorick

この線

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

と同じだろう

when(someObject.doSomething(Matchers.any())).thenReturn(true);

そのため、スタブに付加価値がない場合にargumentCaptor.capture()を使用します。 Matchers.any()を使用すると、実際に何が起こるかがわかりやすくなり、読みやすくなります。 argumentCaptor.capture()を使用すると、実際に一致する引数を読み取ることができません。また、any()を使用する代わりに、より多くの情報(予想される引数のクラス)がある場合は、より具体的なマッチャーを使用して、テストを改善できます。

また別の問題:スタブ化するときにargumentCaptor.capture()を使用すると、検証後にキャプチャされる値の数が不明になります。スタブではなく検証中に値をキャプチャしたいのは、その時点ではまだキャプチャする値がないためです。それでは、引数キャプターはスタブ処理中にメソッドをキャプチャしますか?それとも何かをキャプチャしませんか?この質問に対する答えがありません。私はそれを未定義の振る舞いと考え、未定義の振る舞いを使いたくありません。

0