リポジトリのメモリ内実装をテストしないように注意してください。それは価値がなく、テストの目的ではありません。通常、テストする必要があるのは、サービスおよびビジネス ロジック コード、コントローラー アクションなど、リポジトリを使用するコードです。
とはいえ、すべてのテストで使用する単一のモック リポジトリを使用する必要はありません。多くの場合、テスト ケースごとに異なるテスト リポジトリ (またはリポジトリのフラグメントのみ) を用意することは理にかなっています。
たとえば、同時実行例外が発生した場合にアプリケーション コードの動作をテストする必要がある場合は、次のようなモック リポジトリ メソッドを記述します。
public void Update(T entity)
{
throw new DbConcurrencyException();
}
同様に、同じデータベースで動作する複数のスレッド、プロセス、またはユーザーが関係している場合に重複キー例外が発生する可能性があるすべてのケースをテストすることはできません。このような例外が発生した場合のアプリケーションの動作をテストするには、明示的にスローするだけです。
アプリケーション内の Insert のチェーンが一意のキーのみを使用しているかどうかをテストしたい場合は、はい、次のようなインターフェイスIEntityWithKey
が役立ちます (複合キーに対して 2 つのプロパティを持つこともできます)。次のようなものを使用します。
public void Add(T entity)
{
if (InMemoryListOfT.Any(e => e.Key1 == entity.Key1 && e.Key2 == entity.Key2))
throw new DuplicateKeyException();
InMemoryListOfT.Add(entity);
}
そのような可能性のある状況で、たとえば、特定のエンティティのみOrder
が関与している場合、これを一般的な方法で行う必要さえないと思います。この特別なテストでは、キー インターフェイスを必要としない次のようなリポジトリ メソッドを使用することもできます。
public void Add(T entity)
{
if (entity is Order)
{
var order = entity as Order;
var inMemoryListOfOrder = InMemoryListOfT as List<Order>;
if (inMemoryListOfOrder.Any(o => o.OrderId == order.OrderId))
throw new DuplicateKeyException();
}
InMemoryListOfT.Add(entity);
}
単体テストのためにリポジトリからデータを返すことは、通常、テストの「配置」部分に属します。それは言います:リポジトリからエンティティを返し、これまたはそのメソッドを呼び出すと(「Act」)、次の結果が期待されます(「Assert」)。エンティティを取得する方法は、テスト対象の一部ではありません。new
テスト リポジトリのメソッドでエンティティを作成するだけでFind
よく、これに「主キー」を使用するかどうかは問題ではありません。取得の失敗をシミュレートしたい場合はnull
、テスト リポジトリから戻ってください。
どんなに頑張っても、Entity Framework とまったく同じように動作するインメモリ モック実装を作成することはできず、データベースは運用環境で動作します。これは、実際の EF プロバイダーと実際のデータベース システムを使用する統合テストでのみ完全にカバーできるインフラストラクチャ コードです。
LINQ クエリに関するテストを信頼することさえできません (プライマリ キーを使用しているか、エンティティのその他のプロパティを使用しているかにかかわらず)。それらはメモリ内で動作する可能性がありますが (LINQ-to-Objects)、Entity Framework を使用すると例外で失敗する可能性があるためです (LINQ -to-Entities)、それらが失敗するかどうかは、EF プロバイダーとデータベース システムに依存する場合もあります。
ここでは、 Entity Framework クエリをテストしようとするときに直面する問題について、非常に詳細な回答と多くの例を示します。