web-dev-qa-db-ja.com

単体テストで、なぜリポジトリを2回作成するのですか?

先日私はユニットテストについて少し読んでいて、人々がリポジトリインターフェイス(つまりIExampleRepository)を作成してから実際のリポジトリ(public class ExampleRepository : IExampleRepository)と単体テストに使用するリポジトリ(FakeExampleRepository : IExampleRepository)。

IExampleRepositoryでは、ExampleRepositoryと同じメソッドを実装していましたが、Linqクエリは異なりました。

ここの目的は何ですか?コードの単体テストの一部は、メソッドが正しく機能することを確認することだと思いましたか?しかし、2つのまったく異なるクエリを使用すると、1つは「実際の」クエリで、もう1つはテストで使用された場合、テストはどの程度意味がありますか?

10
jao

単体テストの目的の1つは、一度に1つだけをテストすることです。つまり、単一のクラスとメソッドです。リポジトリ自体がテスト中でない場合は、通常、メソッド/クラスのロジックをテストするために、何らかの方法でこれをモックアウトします。

つまり、「実際の」リポジトリ*でもテストする必要がありますが、これは通常、統合/システムテストで行われます。

*テスト用に設定されたレポのように明らかに現実的です。本番DB。

8
jk.

Jkの2つの回答に同意します。ヤンヒューデック-いくつかの本当に良い情報を提供します。しかし、少し追加すると思いました。

最初の質問(「ここでの目的は何ですか?」)は重要です。あなたが説明している場合、本当の目的は、リポジトリの実装をテストするのではなく、IExampleRepositoryインターフェースを利用しているクラスをテストすることです。 FakeExampleRepositoryを作成すると、実際のリポジトリクラスの詳細を気にすることなく、これらのクライアントクラスをテストできます。

これは、設定しようとしているオブジェクトがテストを困難にする場合(たとえば、ファイルシステムへのアクセス、Webサービスの呼び出し、データベースへの通信など)に特に当てはまります。インターフェース(および他のそのような手法)を使用することにより、カップリングを低く保ちます。したがって、クラスXはインターフェースについてのみ知る必要があり、実装の詳細について知る必要はありません。目的は、クラスXが正しいことを実行していることを確認することです。

モッキング(またはスタブ、偽造...微妙な違いがあります)は、単体テストとTDDのための強力なツールです。しかし、これらの実装を手動で作成して維持するのは面倒です。そのため、ほとんどの言語に役立つモックライブラリがあります。 C#を使用しているので、 Moq をお勧めします。シンプルで非常に強力だからです。その後、モック実装用の追加コードを積み上げることなく、インターフェースに対してテストできます。

5
Allan

ここの目的は何ですか?

分離

ユニットテストのアイデアは、コードの可能な限り最小のunitをテストすることです。これを行うには、テスト内の他のすべての製品コードから分離します。

偽のクラスを作成することで、テスト対象のクラスのみが本番用コードになります。

偽のリポジトリを正しく作成してテストが失敗した場合、問題はテスト対象のコードにあることがわかります。これにより、診断のメリットが無料で得られます。

分離フレームワーク(@ Moq など)を見て、これらの偽物をすばやく生成してテスト条件を設定し、それらを使用してアサートすることができるようにします。

5
StuperUser

単体テストにモックインスタンスを提供する理由は3つあります。

  1. テストの範囲を制限して、テストが宛先のバグの影響を受けないようにします。おそらく、まだ完了していないか、安定していないか、他の誰かのバグがテストに影響を与えたくないためです。
  2. 被扶養者はセットアップが複雑です。たとえば、実際のデータアクセスレイヤーは、実際にテストデータベースをセットアップする必要があるため、モックアウトされることがよくあります。実際のデータアクセスレイヤーをテストする必要がありますが、他のものをデバッグするときに、コストのかかるセットアップを制限できます。
  3. 依存クラスがさまざまな種類のエラーに適切に反応することをテストするには、あらゆる種類の間違った答えを返すモックバージョンを提供します。多くの故障モードは再現がかなり困難ですが、まだテストする必要があるためです。
4
Jan Hudec