52

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

Gived / Will: given(yourMethod())。willThrow(OutOfMemoryException.class);

Do / When: doReturn(7).when(yourMock.fizzBu​​zz());

Will / Given / Do: willReturn(any())。given(yourMethod())。doNothing();

検証/実行: verify(yourMethod())。doThrow(SomeException.class);

私が窒息しているのは、テストケースをモデル化するためのメソッド呼び出しの適切なパターン/組み合わせを選択する方法です。一見無限のコンボでこれらをデイジーチェーン接続できるようですが、どのパターンがどの問題に適しているかはわかりません。

一部のMockitoの達人は、どのタイプのテストケースにどのパターン/組み合わせのMockitoメソッドが使用されているか(およびその理由)を明らかにするのに役立ちますか?前もって感謝します!

4

3 に答える 3

40

when/thenReturnwhen/thenThrowおよびwhen/then構文にはいくつかの欠点があります。例えば、

  • when/thenReturn場合、戻り型がワイルドカードを含むジェネリックであり、同じ型のモックを返したい場合は、コンパイルの警告を回避することはできません。
  • when/thenThrowおよびwhen/thenをvoidメソッドに使用することはできません。
  • これらの構文をMockitoスパイで使用することはできません。
  • whenモックを呼び出さない限り、モックオブジェクト、メソッド、および引数の組み合わせごとに1回だけ呼び出すことができますreset
  • when引数マッチャーを使用しているときに、モックオブジェクトとメソッドの1つの組み合わせを複数回呼び出すと、問題が発生する可能性があります。

これらのケースを覚えるのは難しいと思います。when/thenReturnしたがって、、when/thenThrowおよび構文が機能する場合と機能しない場合を追跡しようとするの when/thenではなく、それらを完全に避けてdoReturn/whendoThrow/whenおよびdoAnswer/when代替を優先します。つまり、、、が必要doReturn/whenになることがあり、これらのメソッドはいつでも使用できるため、、、およびの使用方法を学習しても意味がありdoThrow/whenません。doAnswer/whenwhen/thenReturnwhen/thenThrowwhen/then

、、およびは、、、およびと同じ方法でチェーン接続できることにdoReturn注意してください。彼らが持っていないのは、とへの単一の呼び出し内でいくつかの値を返す(またはいくつかの例外をスローするか、いくつかの答えを実行する)ためのオプションです。しかし、私はこれを行う必要があることはめったにないので、それは実際には問題ではないことがわかりました。doThrowdoAnswerthenReturnthenThrowthendoReturndoThrowdoAnswer

にはもう1つ欠点がありますがdoReturn、これは重要ではないと思います。の場合のように、引数の型のコンパイル時チェックは行われませんwhen/thenReturn。したがって、引数の型を間違えた場合、テストを実行するまでわかりません。率直に言って、私は気にしません。

要約すると、私はMockitoを2年以上使用しており、を一貫して使用することをMockitoのベストプラクティスと考えてdoReturnいますdoThrowdoAnswer他のMockitoユーザーは同意しません。

于 2012-07-14T01:02:51.800 に答える
18

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>());
于 2012-07-13T01:54:19.197 に答える
10

実際、物事はあなたが思っていたよりもはるかに単純に見えます

参照:http ://static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html

確認

Mockitoを使用するには、Mockitoの1つの基本的な哲学を理解する必要があります。それは、スタブと検証が分離されていることです。したがって、あなたが言及した「検証/実行」は実際には「検証」ジョブを実行し、他の4つの「文法」はスタブ用です。スタブは、モックオブジェクトがさまざまな状況でどのように反応するかを定義します。検証は、テスト対象システム(SUT)への以前の呼び出しで、モックが期待どおりに呼び出されていることを確認することです。

いつ/その後、与えられた/意志

それからそれは「いつ」そして「与えられた」家族に来ます。あなたは単にそれらをお互いのエイリアスとして扱うことができます。「Given」ファミリがMockito1.8.xに追加され、BDDプラクティスにより適合しているように見えます。

DoXxx

通常の場合、主にwhen(xxx).then(...)(およびgiven(...).will(...))を使用します。ただし、構文が機能しない場合があります。最も明白なケースは、スタブメソッドのreturnタイプがvoidの場合です。このような場合when(mockObj.voidMethod()).thenThrow(anException)、コンパイルは行われません。回避策として、Do / Whenの代替構文が作成されるため、前の行を次のように記述できます。doThrow(anException).when(mockObj.voidMethod())

于 2012-07-13T04:18:40.893 に答える