2012-04-12 23 views
30

統合テストに必要な多くの依存関係をどうやって模擬しますか?統合テストのためのモック

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

今すぐ統合テストが行​​われます。のは、この場合には、統合テストはこのような何かをテストしますと言ってみましょう:

  1. メッセージがキューに置かれ
  2. メッセージが
  3. 応答メッセージが応答キュー
に置かれている「処理済み」されます

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

これらの依存関係のそれぞれは、単一のステートレスサービスクラスによってラップされています。

どのように人々がこれを処理していますか?

私はMockitoを使用して、上記の流れに伴う副作用を確認することができます。しかし、Mocktioのドキュメンテーション(そして大部分は実装です)は、「純粋な」単体テスト以外の文脈でそれを使用することに対して強く反対しているようです。私はこのルートを行くことを試みたが、

  • それは
  • それは春は私の豆にそれらのスタブのインスタンスを注入持ってすることは困難ですが、
  • それは難しい(それがたくさんありますよう)スタブデータを移入することは困難ですスタブをクリアすることなく、別の一連の相互作用を検証できるようにモックを「リセット」します。

EDIT

私はHSQLDBインスタンスのようなもので、データベースの問題を扱うことができることを知っているが、外部サービスの問題がまだあります。再現性のために、私はこれらのサービスが稼働していること、私が必要とする状態にいることなどに頼ることはできません。

Whatdayaですか?

+1

統合テストは2通りの方法で行うことができます。それはあなたのような統合テストのように聞こえる、接続コンポーネントがうまくいっていることをテストする(本質的にAPIをテストする)。しかし、時には統合とはエンドツーエンドを指すため、サービスを嘲笑せずに実際にデータベースにアクセスできるようにします。この明確化は答えを助けることができます。タイプのさらなる明確化のためにhttp://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-testを参照してください。 –

+0

It実際には、多くの外部依存関係を必要とするテスト(統合またはエンドツーエンド)に適用されます。例えば、データベーススタブをHSQLDBインスタンスに置き換えることができますが、私はまだ他のすべてのサービスを持っています。明確にするために少し質問を編集します.. –

+0

どうしてあなたは嘲笑問題を最終的に解決しましたか? – Pupsik

答えて

7

大きな質問です。

あなたはMockitoの限界にぶつかるようです。オブジェクトのやりとりを調べたいなら、Mockitoは素晴らしいです。

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

ユニットレベルでは、これらのモックは、Mockitoによってうまく生成できます。統合レベルでは、これはますます難しくなり、目的に合わせたテスト容易性インターフェイスが必要になります。

+1

ええ、統合レベルの人たちは、ライブラリを模倣したり、サービス/データベースのテストインスタンスを実際に打つことによって、「それを最大限に活用する」のように思えます。私は現在、GroovyベースのMockito拡張機能を使って、統合テストを少し難しくするのを手伝っています。 –

7

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

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

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

+0

Davidに感謝します。私の外部サービスは非常によく抽象化されており、それぞれが単一のSpring Singletonサービスクラスでラップされています。それでも、複雑なシナリオでは、嘲笑が困難になります。多くのデータがスタブされる必要があります。同じサービスメソッドが何度も呼び出されることがあります。つまり、スタブに複数の値を返さなければならないということです。私は人々がよりクリーンな方法でこれを解決したと仮定する必要があります –

+0

彼らはシングルトンでラップする必要がありますか?シングルトンは嘲笑するのが難しいことが知られています。ラッパーがシングルトンではないように工学的なことができますか? –

+0

また、同じサービスメソッドが1回のテストで何度も呼び出されている理由についても質問します。おそらくあなたのテスト方法は大きすぎますか?私は、「テスト方法ごとに1つのアサート」ルールを確信しています。それは実際にはるかにクリーンなテストのために行います。 –

0

httpまたはrest mockフレームワークがある場合は、それを使用してください。

すべての複雑な依存関係を記録、変更、再生することができます。

関連する問題