different types matchers provided mockito
入出力ファイルc ++
Mockitoのさまざまなタイプのマッチャーの紹介。
Mockitoのモックとスパイ 詳細については、以前のチュートリアルで詳しく説明しました。 Mockitoトレーニングシリーズ 。
マッチャーとは何ですか?
マッチャーは正規表現やワイルドカードのようなもので、特定の入力(および/または出力)の代わりに、スタブ/スパイを休ませたり、スタブへの呼び出しを確認したりできる入力/出力の範囲/タイプを指定します。
すべてのMockitoマッチャーは ‘の一部です Mockito’ 静的クラス。
マッチャーは強力なツールであり、ユースケースやシナリオに応じて、引数入力をジェネリック型として特定の値に言及することで、スタブを設定したり、スタブでの呼び出しを検証したりする簡単な方法を可能にします。
学習内容:
Mockitoのマッチャーの種類
Mockitoには大きく2種類のマッチャーがあります または使用法に関して、マッチャーは以下の2つのカテゴリーに使用できます。
- スタブセットアップ中の引数マッチャー
- スタブへの実際の呼び出しを検証するための検証マッチャー
両方のタイプのマッチャー、つまり引数と検証に対して、Mockitoは膨大なマッチャーのセットを提供します(クリック ここに マッチャーの完全なリストを取得するには)。
引数マッチャー
以下にリストされているのは、最も広く使用されているものです。
以下のすべてについて、IntegerListのテストを検討しましょう。
final List mockedIntList = mock(ArrayList.class);
#1) any()–任意のオブジェクト(nullを含む)を受け入れます。
when (mockedIntList.get( any ())).thenReturn(3);
#二) any(java言語クラス)–
例 :any(ClassUnderTest.class)–これはany()のより具体的なバリアントであり、テンプレートパラメータとして言及されているクラスタイプのオブジェクトのみを受け入れます。
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
#3) anyBoolean()、anyByte()、anyInt()、anyString()、anyDouble()、anyFloat()、anyList()など–これらはすべて、対応するデータ型の任意のオブジェクトとnull値を受け入れます。
when (mockedIntList.get( any Int())).thenReturn(3);
#4) 特定の引数–実際の引数が事前にわかっている場合は、一般的な引数タイプよりも信頼性が高いため、常にそれらを使用することをお勧めします。
例:
when(mockedIntList.get(1)).thenReturn(3);
検証マッチャー
いいえのようなことを期待/主張するために利用できるいくつかの特殊なマッチャーがあります。モックでの呼び出しの。
以下のすべてのマッチャーについて、以前に使用したものと同じ例のリストを考えてみましょう。
final List mockedIntList = mock(ArrayList.class);
#1)模擬呼び出し
(私) モックでの単純な呼び出しは、モックリストのサイズを5に設定することにより、モックされたメソッドが呼び出された/対話されたかどうかを確認します。
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList).size();
(ii) モックされたメソッドとの相互作用の特定のカウントは、noのカウントを検証します。何度もモックが呼ばれると予想されていました。
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(1)).size();
相互作用が0であることを確認するには、times()マッチャーの引数として値を1から0に変更するだけです。
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(0)).size();
失敗した場合、次の例外が返されます。
に) 予想される呼び出しが実際の呼び出しよりも少ない場合:
例: 2回欲しかったが、3回呼び出された後、Mockitoは戻ります–「 検証.TooManyActualInvocations 「」
コード例:
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(2)).get(anyInt());
b) 予想される呼び出しが実際の呼び出しよりも多い場合:
例: 2回欲しかったが、1回呼び出された後、Mockitoは戻ります–「 検証.TooLittleActualInvocations 「」
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(4)).get(anyInt());
(iii) モックオブジェクトの特定のメソッドとの相互作用はありません。
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); // Assert verify(mockedIntList, never()).size();
(iv) モックされた相互作用の順序を確認する–これは、モックされたオブジェクトのメソッドが呼び出された順序を確認する場合に特に便利です。
例: データベースの更新が行われた順序をテストで検証する必要があるデータベースのような操作。
これを例で説明する –同じ例のリストを続けましょう。
ここで、リストメソッドの呼び出しの順序が順番になっていると仮定します。つまり、get(5)、size()、get(2)です。したがって、検証の順序も同じである必要があります。
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size(); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt());
検証シーケンスが間違っている場合、Mockitoによって例外がスローされます。 検証.VerificationInOrderFailure 」。
したがって、上記の例では、最後の2行を交換して検証の順序を変更すると、VerificationInOrderFailure例外が発生し始めます。
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size();
(v) インタラクションが少なくとも/最大回数発生したことを確認します。
(に) 少なくとも:
例: atleast(3)–モックオブジェクトがテスト中に少なくとも3回呼び出され/相互作用したことを確認します。したがって、相互作用が3または3より大きい場合は、検証が成功するはずです。
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atLeast(2)).get(anyInt());
エラーの場合、つまり実際の呼び出しが一致しない場合は、times()マッチャーの場合と同じ例外がスローされます。 検証。TooLittleActualInvocations」
どのWindowsオペレーティングシステムが最適か
(b) せいぜい:
例: atmost(3)–モックされたオブジェクトがテスト中に最大3回呼び出され/相互作用したかどうかを検証します。したがって、モックとの0、1、2、または3の相互作用のいずれかにより、検証が成功するはずです。
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atMost(2)).get(anyInt()); verify(mockedIntList, atMost(2)).size();
#2)引数のマッチング
上記の呼び出しでは、マッチャーを引数マッチャーと組み合わせて、モックが呼び出された引数を検証できます。
- どれか()
- 特定の値–引数が事前にわかっている場合は、特定の値で確認します。
- anyInt()、anyString()などの他の引数マッチャー。
ヒントとコツ
#1)検証中に引数キャプチャを使用する
引数キャプチャ検証は、通常、スタブされたメソッドで使用される引数がメソッド呼び出しを介して直接渡されるのではなく、テスト対象のメソッドが呼び出されたときに内部的に作成される場合に役立ちます。
これは、動作がスタブされた1人以上の共同作業者にメソッドが依存している場合に本質的に役立ちます。これらの共同作業者に渡される引数は、内部オブジェクトまたはまったく新しい引数セットです。
コラボレーターが呼び出された実際の引数を検証することで、テストされるコードに大きな信頼を置くことができます。
Mockitoは、検証で使用できるArgumentCaptorを提供します。その後、「AgumentCaptor.getValue()」が呼び出されると、実際にキャプチャされた引数を予期された引数に対してアサートできます。
これを説明するために、以下の例を参照してください。
以下のメソッドでは、calculatePriceは、InventoryModelクラスがメソッド本体内に作成され、InventoryServiceが更新に使用するモデルです。
アニメを無料で視聴するウェブサイト
ここで、inventoryServiceが呼び出された引数を検証するテストを作成する場合は、InventoryModelクラスタイプのArgumentCaptorオブジェクトを使用するだけで済みます。
テスト中の方法:
public double calculatePrice(int itemSkuCode) { double price = 0; // get Item details ItemSku sku = itemService.getItemDetails(itemSkuCode); // update item inventory InventoryModel model = new InventoryModel(); model.setItemSku(sku); model.setItemSuppliers(new String(){'Supplier1'}); inventoryService.updateInventory(model, 1); return sku.getPrice(); }
テストコード: InventoryServiceが検証される検証ステップを見てください。argumentCaptorオブジェクトが、一致する必要のある引数に置き換えられています。
次に、ArgumentCaptorオブジェクトでgetValue()メソッドを呼び出して、値をアサートするだけです。
例: ArgumentCaptorObject.getValue()
public void calculatePrice_withValidItemSku_returnsSuccess() { // Arrange ItemSku item1 = new ItemSku(); item1.setApplicableDiscount(5.00); item1.setPrice(100.00); CustomerProfile customerProfile = new CustomerProfile(); customerProfile.setExtraLoyaltyDiscountPercentage(2.00); double expectedPrice = 93.00; // Arrange when(mockedItemService.getItemDetails(anyInt())).thenReturn(item1); ArgumentCaptor argCaptorInventoryModel = ArgumentCaptor.forClass(InventoryModel.class); // Act priceCalculator.calculatePrice(1234); // Assert verify(mockedItemService).getItemDetails(anyInt()); verify(mockedInventoryService).updateInventory(argCaptorInventoryModel.capture(), eq(1)); assertEquals(argCaptorInventoryModel.getValue().itemSku, item1);
ArgumentCaptorがないと、サービス呼び出しが行われた引数を特定する方法はありません。可能な限り、「any()」または「any(InventoryModel.class)」を使用して引数を検証することをお勧めします。
#2)マッチャー使用時の一般的な例外/エラー
マッチャーを使用している間は、従う必要のある特定の規則があります。従わないと、例外がスローされます。私が遭遇した最も一般的なものは、スタブと検証中です。
いずれかのargumentMatchersを使用していて、スタブメソッドに複数の引数がある場合は、すべての引数をマッチャーで指定する必要があります。そうでない場合は、どの引数にもマッチャーを含めることはできません。 さて、これはどういう意味ですか?
シナリオでこれを理解してみましょう(そしてこのシナリオのコードサンプル)
- テスト中のメソッドに次のようなシグネチャがあるとします–
concatenateString(String arg1、String arg2) - スタブするとき– arg1の値はわかっているが、arg2は不明であるため、– any()やanyString()のような引数マッチャーを使用し、テキスト「hello」のように最初の引数の値を指定することにします。
- 上記の手順を実行してテストを実行すると、テストは「InvalidUseOfMatchersException」という例外をスローします。
例を使ってこれを理解してみましょう。
テストコード:
// Arrange when(a gMatcher.concatenateString('hello', anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
テスト中のクラス:
public class ArgMatcher { public String concatenateString(String arg1, String arg2) { return arg1.concat(arg2); } }
上記のテストを実行すると、「 InvalidUseOfMatchersException 「」
さて、この例外の理由は何ですか?
これは、パーツマッチャーとパーツ固定文字列を使用したスタブです。つまり、1つの引数マッチャーを「hello」、2番目をanyString()と呼びました。現在、これらの種類の例外を取り除くには2つの方法があります(また、この動作はモック設定と動作の両方に適用されることに注意してください)。
#1)すべての引数に引数マッチャーを使用します。
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
#2)引数がわかっている引数マッチャーとしてeq()を使用します。したがって、引数を「hello」として指定する代わりに、「eq(「hello」)」として指定すると、スタブが成功するはずです。
// Arrange when(argMatcher.concatenateString(anyString(), eq('world'))).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'world'); // Assert verify(argMatcher).concatenateString(anyString(), eq('world'));
結論
この記事では、Mockitoが提供するさまざまなタイプのマッチャーの使用方法を説明しました。
ここでは、最も広く使用されているものについて説明しました。完全なリストを参照するには、Mockitoライブラリのドキュメントが参考になります。
モックのプライベートメソッド、スタティックメソッド、ボイドメソッドの詳細については、今後のチュートリアルをご覧ください。