リポジトリが行うことは、ドメインからNHibernateやDoctrineなどのDALフレームワーク、またはSQL実行クラスに変換することです。これは、リポジトリがそのフレームワークのメソッドを呼び出してその職務を実行することを意味します。リポジトリは、データをフェッチするために必要なクエリを構築します。ORMフレームワークを使用していない場合(そうだといいのですが...)、リポジトリは生のSQLステートメントが構築される場所です。
これらのメソッドの最も基本的なものは保存です。ほとんどの場合、これはオブジェクトをリポジトリから作業ユニット(またはセッション)に渡すだけです。
public void Save(Car car)
{
session.Save(car);
}
しかし、別の例を見てみましょう。たとえば、IDで自動車を取得します。それは次のようになるかもしれません
public function GetCarWithId(String id)
{
return Session.QueryOver<Car>()
.Where(x => x.Id == id)
.SingleOrDefault();
}
まだそれほど複雑ではありませんが、複数の条件で想像できます(「フォルクスワーゲン」グループのすべてのブランドについて2010年以降に製造されたすべての車を入手してください)。これはトリッキーです。したがって、真のTDDの方法では、これをテストする必要があります。これを行うにはいくつかの方法があります。
オプション1:ORMフレームワークに対して行われた呼び出しをモックする
もちろん、Sessionオブジェクトをモックして、適切な呼び出しが行われたことを単純に主張できます。これはリポジトリをテストしますが、リポジトリが内部的に希望どおりに見えることをテストしているだけなので、実際にはテスト駆動ではありません。テストは基本的に「コードはこのように見えるはずです」と述べています。それでも、それは有効なアプローチですが、この種のテストにはほとんど価値がないように感じます。
オプション2:テストからデータベースを(再)構築する
一部のDALフレームワークでは、ドメインをテーブルにマップするために作成したマッピングファイルに基づいて、データベースの完全な構造を構築できます。これらのフレームワークの場合、リポジトリをテストする方法は、テストの最初のステップでメモリ内データベースを使用してデータベースを作成し、DALフレームワークを使用してオブジェクトをメモリ内データベースに追加することです。この後、メモリ内データベースのリポジトリを使用して、メソッドが機能するかどうかをテストできます。これらのテストは低速ですが、非常に有効であり、テストを実行します。DALフレームワークからの協力が必要です。
オプション3:実際のデータベースでテストする
別のアプローチは、実際のデータベースでテストし、ユニットテストを分離することです。いくつかの方法でこれを行うことができます:テストをトランザクションで囲む、手動でクリーンアップする(保守が非常に難しいことはお勧めしません)、各ステップの後にデータベースを完全に再構築します...構築しているアプリケーションに応じて、これは実現可能ではありません。私のアプリケーションでは、ソース管理からローカル開発データベースを完全に構築でき、リポジトリのユニットテストではトランザクションを使用して、テストを相互に完全に分離します(オープントランザクション、データの挿入、テストリポジトリ、ロールバックトランザクション)。すべてのビルドでは、最初にローカル開発データベースをセットアップしてから、そのローカル開発データベース上のリポジトリに対してトランザクション分離の単体テストを実行します。それ'
DALをテストしない
NHibernateなどのDALフレームワークを使用している場合は、そのフレームワークをテストする必要はありません。ドメインオブジェクトを保存、取得、比較してマッピングファイルをテストし、すべてが問題ないことを確認できます(必ず、あらゆる種類のキャッシュを無効にしてください)が、他の多くのテストほど必要ではありません。私はこれを主に、子供たちに条件がある親のコレクションのために行う傾向があります。
リポジトリの戻りをテストするときは、ドメインオブジェクトの特定のプロパティが一致するかどうかを確認するだけです。これはIDにすることもできますが、テストでは人間が読み取り可能なプロパティを確認する方が多くの場合有益です。「2010年以降に製造されたすべての車を入手してください...」では、5台の車が返され、ナンバープレートが「ここにリストを挿入」していることを簡単に確認できます。追加の利点は、ソートについて考えることを強制し、テストで自動的にソートを強制することです。あなたは驚かれると思いますどのように多くのアプリケーションのいずれかの並べ替えを複数回(リターンが同じ敷地内のすべてのソートビューオブジェクトを作成する前にして、ソートビューオブジェクト、データベースから選別念のためか、暗黙的にリポジトリの種類を前提とし、誤って削除します)途中でUIが壊れました。
「単体テスト」は単なる名前です
私の意見では、ユニットテストは必要があり、主にデータベースをヒットしません。ソースからのデータを必要とするすべてのコードがリポジトリを使用してこれを実行し、そのリポジトリが依存関係として挿入されるように、アプリケーションを構築します。これにより、簡単なモックと必要なすべてのTDDの良さが実現します。しかし、最終的には、リポジトリがその役割を果たしていることを確認し、それを行う最も簡単な方法がデータベースにヒットする場合は、そうする必要があります。私は長い間、「単体テストはデータベースに触れてはならない」という考えを手放し、これを行うには非常に現実的な理由があることを学びました。ただし、これを自動的かつ繰り返し実行できる場合のみ。そして、そのようなテストを「単体テスト」または「統合テスト」と呼ぶ天候は悲観的です。