Mockitoは、Javaのためのかなり甘いスタブ/モックフレームワークのようです。唯一の問題は、APIの最適な使用方法に関する具体的なドキュメントが見つからないことです。テストで使用される一般的な方法は次のとおりです。
doXXX(???) : Stubber
when(T) : OngoingStubbing
then(T) : OngoingStubbing
verify(???) : T
given(T) : BDDOngoingStubbing
willXXX(???) : BDDStubber
実際にMockitoの例を見ると、次のようなコードが表示されます。
when(yourMethod()).thenReturn(5);
私が読んだすべてのドキュメントから、上記の例のようにこれらのメソッド呼び出しをデイジーチェーンで連結することで得られたMockitoの「文法」のいくつかの「パターン」を特定しました。私が見つけたいくつかの一般的なパターンは次のとおりです。
When/Then: when(yourMethod())。thenReturn(5);
Given/Will: given(yourMethod())。willThrow(OutOfMemoryException.class);
Do/When: doReturn(7).when(yourMock.fizzBuzz());
Will/Given/Do: willReturn(any())。given(yourMethod())。doNothing();
Verify/Do: verify(yourMethod())。doThrow(SomeException.class);
テストケースをモデル化するために、メソッド呼び出しの正しいパターン/組み合わせをどのように選択するかが問題になっています。一見無限のコンボでこれらをデイジーチェーンで接続できるようで、どのパターンがどの問題に適しているのかわかりません。
一部のMockito達人は、Mockitoメソッドのどのパターン/組み合わせがどのタイプのテストケース(およびその理由)に使用されるかについて、いくつかの光を当てるのに役立ちますか?前もって感謝します!
Mockitoには多くの場合、いくつかの方法があります。
私は自分が主に使用していることに気づきます:
// Setup expectations
when(object.method()).thenReturn(value);
when(object.method()).thenThrow(exception);
doThrow(exception).when(object.voidMethod());
// verify things
verify(object, times(2)).method();
verify(object, times(1)).voidMethod();
これらの3種類の呼び出しで、必要なものの95%を実行できることがわかりました。
また、使用しているMockitoのバージョンは何ですか? "given"および "will"構成は最新バージョン(1.9.0以降)には存在しません
ただし、戻り値または例外を入力に応答させたい場合があります。この場合、Answerインターフェイスを使用してメソッドの引数を検査し、適切な値を返すことができます。
public class ReturnFirstArg<T> implements Answer<T> {
public T answer(InvocationOnMock invocation) {
return invocation.getArguments()[0];
}
}
when(object.method(7)).thenAnswer(new ReturnFirstArg<Integer>());
when/thenReturn
、when/thenThrow
、when/then
の構文にはいくつかの欠点があります。例えば、
when/thenReturn
の場合、戻り値の型がワイルドカードを使用したジェネリックであり、同じ型のモックを返したい場合、コンパイル警告を回避することはできません。when/thenThrow
およびwhen/then
を使用することはできません。when
を呼び出さない限り、モックオブジェクト、メソッド、引数の組み合わせごとに一度だけreset
を呼び出すことができます。when
を複数回呼び出すと、問題が発生する可能性があります。これらのケースを覚えるのは難しいと思います。したがって、when/thenReturn
、when/thenThrow
、およびwhen/then
構文がいつ機能するか、または機能しないかを追跡する代わりに、doReturn/when
、doThrow/when
、およびdoAnswer/when
の代替を優先して、それらを完全に回避することをお勧めします。つまり、doReturn/when
、doThrow/when
、doAnswer/when
が必要になる場合があり、常にこれらのメソッドを使用できるため、when/thenReturn
、when/thenThrow
、when/then
の使用方法を学習しても意味がありません。
doReturn
、doThrow
、doAnswer
は、thenReturn
、thenThrow
、then
と同じ方法で連結できます。 doReturn
、doThrow
、doAnswer
への1回の呼び出しで複数の値を返す(またはいくつかの例外をスローする、または複数の応答を実行する)オプションはありません。しかし、これを行う必要はあまりないので、それほど重要ではありません。
doReturn
にはもう1つ不利な点があります。 when/thenReturn
の場合のように、引数の型のコンパイル時チェックを取得しません。したがって、引数の型が間違っていると、テストを実行するまでわかりません。率直に言って、私は気にしません。
要約すると、私はMockitoを2年以上使用しており、doReturn
、doThrow
、doAnswer
の一貫した使用がMockitoのベストプラクティスであると考えています。他のMockitoユーザーは同意しません。
実際のところ、思ったよりずっとシンプルに見えます
REF: http://static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html
確認:
Mockitoを使用するには、Mockitoの基本的な哲学の1つを理解する必要があります。スタブと検証は分離されています。したがって、あなたが言及した「検証/実行」は実際には「検証」ジョブを実行しているのに対し、他の4つの「文法」はスタブ用です。スタブは、モックオブジェクトがさまざまな状況でどのように反応するかを定義します。検証は、テスト対象システム(SUT)への以前の呼び出しで、モックが期待どおりに呼び出されることを確認することです。
When/Then、Given/Will:
それからそれは「いつ」および「与えられた」家族に来ます。単にそれらを互いのエイリアスとして扱うことができます。 "Given"ファミリは、BDDプラクティスに合わせて見えるようにするためにMockito 1.8.xに追加されました。
DoXxx:
通常のケースでは、主にwhen(xxx).then(...)
(およびgiven(...).will(...)
)を使用します。ただし、構文が機能しない場合があります。最も明白なケースは、スタブ化されたメソッドの戻り値の型がvoidである場合です。そのような場合、when(mockObj.voidMethod()).thenThrow(anException)
はコンパイルされません。回避策として、Do/Whenの代替構文が作成されるため、前の行をdoThrow(anException).when(mockObj.voidMethod())
として記述できます