web-dev-qa-db-ja.com

統合テストのモック

統合テストに必要な多くの依存関係をどのように模倣しますか?

私は「純粋な」単体テストにMockitoを使用しています。この場合の「純粋」とは、単一のクラスをテストし、そのすべての依存関係を模擬することを意味します。綺麗な。

次に統合テストが行​​われます。この場合、統合テストが次のようなものをテストするとします。

  1. メッセージはキューに入れられます
  2. メッセージは「処理されました」
  3. 応答メッセージは応答キューに入れられます

また、ステップ2で行われる処理は深刻なものであるとしましょう。それは多くのデータベースの相互作用、複数の外部サービス、ファイルシステム、あらゆる種類のものに依存しています。フローがトリガーする副作用もたくさんあるので、応答が正しいことを単純に確認することはできません。副作用を確認する必要があります。

これらの依存関係はそれぞれ、単一のステートレスサービスクラスによってラップされているため、ニースでモック可能になっています。

人々はこれをどのように扱っていますか?

上記のフローの副作用を確認できるように、Mockitoを使用したいと思います。ただし、Mocktioのドキュメント(および大部分はその実装)は、「純粋な」単体テスト以外のコンテキストでの使用とは強く闘っているようです。私はこのルートに行こうとしましたが、

  • (たくさんあるので)スタブデータを投入するのは難しい
  • Springがこれらのスタブされたインスタンスを私のBeanに注入するのは難しい
  • モックを「リセット」して、スタブをクリアせずに別の相互作用のセットを確認できるようにするのは困難です。

[〜#〜]編集[〜#〜]

HSQLDBインスタンスのようなものでデータベースの問題を処理できることはわかっていますが、外部サービスの問題はまだ残っています。再現性のために、これらのサービスが稼働している、必要な状態にある、などと信頼することはできません。そこにある唯一の選択肢は、それらをモックすることです。

何だよ?

38
Roy Truelove

すばらしい質問です。

Mockitoの限界に達したようです。オブジェクトの相互作用を検査したい場合は、Mockitoが最適です。

ただし、必要なのは、より高い抽象化レベルでの可観測性(および制御可能性)のようです。そのために必要なモックまたはスタブは、注意深く設計され、手作りされている必要があります。

ユニットレベルでは、これらのモックはMockitoを使用して適切に生成できます。統合レベルでは、これははるかに困難になり、専用のテスト容易性インターフェースが必要になります。

8
avandeursen

データベース、Webサービス、ファイルシステムなどのモックを作成するには、おそらく少しリファクタリングする必要があります。外部サービスごとに、実行する各操作のメソッドを持つラッパークラスを記述する必要があります。このような各メソッドには実際のロジックはありませんが、外部サービスが理解できる方法でパラメーターを渡し、外部サービスが返すデータを含むオブジェクトを返します。たとえば、データベースとやり取りしている場合、ラッパークラスはそのパラメーターをSQLステートメントにフォーマットし、それらを既存のConnectionオブジェクトに送信して、結果のListを返す場合があります。

ラッパークラスのメソッドにはロジックが含まれていないため(つまり、if/else、ループ、例外処理は含まれていません)、ラッパークラスを単体テストする必要はありません。ラッパークラスを統合テストして、その責任が正しく実行されることを確認する必要があります(つまり、SQLステートメントがデータベースに望ましい影響を与えるなど)。

次に、外部サービスと対話するクラスを書き直して、代わりにラッパークラスと対話するようにします。その後、それらを単体テストするのは簡単です。ラッパークラスをモックするだけです。

8