ここで検討しなければならない問題が2つあります。
1つ目は、単体テストの観点からすべてのテストを見ているように見えることです。単体テストは非常に価値がありますが、唯一のテストではありません。テストは実際には非常に速いから、いくつかの異なる層に分けることができますユニットテスト少なく、高速に統合テストでも遅くに受け入れテスト。(機能テストのように、さらに多くのレイヤーが分割される可能性があります。)
2つ目は、サードパーティのコードへの呼び出しをビジネスロジックと組み合わせて、テストの課題を作成し、コードをより脆弱にする可能性があることです。
単体テストは高速で、頻繁に実行する必要があります。依存関係のモックは、これらのテストを高速に実行し続けるのに役立ちますが、依存関係が変更され、モックが変更されない場合、カバレッジにホールが生じる可能性があります。テストがまだ緑色で実行されている間に、コードが破損する可能性があります。依存関係のインターフェイスが変更された場合に警告するモックライブラリもあれば、できないものもあります。
一方、統合テストは、サードパーティライブラリを含むコンポーネント間の相互作用をテストするように設計されています。実際のオブジェクトがどのように相互作用するかを確認するため、このレベルのテストではモックを使用しないでください。実際のオブジェクトを使用しているため、これらのテストは遅くなり、ユニットテストほど頻繁には実行されません。
受け入れテストでは、さらに高いレベルで、ソフトウェアの要件が満たされているかどうかをテストします。これらのテストは、展開される完全なシステム全体に対して実行されます。繰り返しますが、モックは使用しないでください。
モックに関して価値があるとわかったガイドラインの一つは、自分が所有していないタイプをモックしないことです。AmazonはS3のAPIを所有しているため、S3の下でAPIが変更されないようにすることができます。一方、あなたはこれらの保証を持っていません。したがって、テストでS3 APIをモックアウトすると、コードが変更されて破損する可能性がありますが、テストはすべて緑色で表示されます。では、サードパーティのライブラリを使用するコードをどのように単体テストするのでしょうか?
まあ、私たちはしません。ガイドラインに従うと、所有していないオブジェクトをモックすることはできません。しかし…直接的な依存関係を所有している場合、それらをモックすることができます。しかし、どのように?S3 APIの独自のラッパーを作成します。S3 APIによく似た外観にすることも、ニーズにさらに近づけることもできます(推奨)。私たちも言って、それはもう少し抽象的な作ることができるPersistenceService
のではなくをAmazonS3Bucket
。PersistenceService
以下のようなメソッドとのインタフェースになる#save(Thing)
と#fetch(ThingId)
、我々は(これらは、あなたが実際には別の方法をお勧めします、例です)見たいかもしれない方法の種類。これでPersistenceService
、S3 APIの周りにを実装して(たとえばS3PersistenceService
)、呼び出しコードからカプセル化することができます。
次に、S3 APIを呼び出すコードについて説明します。これらの呼び出しをPersistenceService
オブジェクトの呼び出しに置き換える必要があります。依存性注入を使用PersistenceService
して、オブジェクトに渡します。それは重要だないために依頼するS3PersistenceService
、しかしを求めることPersistenceService
。これにより、テスト中に実装を交換できます。
直接S3のAPIを使用するために使用されるすべてのコードは、今、私たちを使用していますPersistenceService
し、私たちはS3PersistenceService
今、S3のAPIへのすべての呼び出しを行います。テストではPersistenceService
、所有しているので、モックアウトでき、モックを使用してコードが正しい呼び出しを行うことを確認します。しかし、今ではテスト方法が残っていますS3PersistenceService
。以前と同じ問題があります。外部サービスを呼び出さずに単体テストを行うことはできません。そのため、ユニットテストは行いません。我々は可能性が S3のAPIの依存関係をモックが、これは私たちに少しツーなし追加の自信を与えるだろう。代わりに、より高いレベルでテストする必要があります:統合テスト。
これは、コードの一部を単体テストしてはならないという厄介な問題に聞こえるかもしれませんが、達成したことを見てみましょう。単体テストができなかった場所に、大量のコードがあり、今ではを通じて単体テストを行うことができますPersistenceService
。単一の実装クラスに限定されたサードパーティライブラリの混乱があります。そのクラスは、APIを使用するために必要な機能を提供する必要がありますが、外部ビジネスロジックはアタッチされていません。したがって、一度作成すると、非常に安定しているはずであり、あまり変更しないでください。コードが安定しているため、それほど頻繁に実行しないより遅いテストに頼ることができます。
次のステップは、の統合テストを作成することですS3PersistenceService
。これらは名前またはフォルダで分離する必要があります。これにより、高速ユニットテストとは別に実行できます。統合テストでは、コードが十分な情報を提供している場合、単体テストと同じテストフレームワークを使用できることが多いため、新しいツールを学ぶ必要はありません。統合テストの実際のコードは、オプション1用に記述するものです。