回答:
テストする次のメソッドを想定します。
public boolean doSomething(SomeClass arg);
Mockitoのドキュメントでは、次のように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));
false
、そうではありませんtrue
。
この線
when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
同じことをするだろう
when(someObject.doSomething(Matchers.any())).thenReturn(true);
したがって、スタブに付加価値がないときにargumentCaptor.capture()を使用します。Matchers.any()を使用すると、実際に何が起こるかがわかりやすくなるため、読みやすさが向上します。argumentCaptor.capture()では、実際に一致する引数を読み取ることはできません。そして、any()を使用する代わりに、より多くの情報(期待される引数のクラス)がある場合、より具体的なマッチャーを使用して、テストを改善できます。
また、別の問題:スタブ時にargumentCaptor.capture()を使用すると、検証後に取得する必要がある値の数が不明確になります。まだキャプチャする値がないため、スタブ中ではなく検証中に値をキャプチャします。では、スタブ中に引数キャプターがメソッドをキャプチャするのは何ですか?またはそれは何かをキャプチャしませんか?この質問に対する答えはありません。私はそれを未定義の動作であると考え、未定義の動作を使用したくありません。
仮に、検索でこの質問にたどり着いた場合は、おそらく次のようになります。
doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));
どうして?私のようにあなたは時間を大切.equals
にし、単一のテストシナリオのためだけに実装するつもりはないからです。
また、テストの99%はMockからnullが返されてバラバラになり、合理的な設計null
では、コストをかけずに戻り、使用Optional
またはKotlinへの移行を回避します。これverify
は、頻繁に使用する必要がないことを意味し、ArgumentCaptorsはあまりに面倒で書くことができません。