ADO .NET Entity Frameworkに対して記述されたコードを単体テストしています。インメモリデータベースに行を入力し、コードがそれらを正しく取得することを確認したいと思います。
RhinoMocksを使用してEntityFrameworkをモックすることはできますが、それだけでは不十分です。どのエンティティを返すかをクエリに指示します。これは、where句も.Include()ステートメントもテストしません。 where句が意図した行のみに一致し、他の行には一致しないことを確認したいと思います。必要なエンティティを要求し、必要のないエンティティは要求していないことを確認したいと思います。
例えば:
class CustomerService
{
ObjectQuery<Customer> _customerSource;
public CustomerService(ObjectQuery<Customer> customerSource)
{
_customerSource = customerSource;
}
public Customer GetCustomerById(int customerId)
{
var customers = from c in _customerSource.Include("Order")
where c.CustomerID == customerId
select c;
return customers.FirstOrDefault();
}
}
ObjectQueryをモックして、注文が入力された既知の顧客を返す場合、CustomerServiceに正しいwhere句とIncludeがあることをどのように知ることができますか?むしろ、いくつかの顧客行といくつかの注文行を挿入してから、適切な顧客が選択され、注文が入力されていることを表明します。
現在、EFのメモリ内プロバイダーはありませんが、Highway.Dataを見ると、基本の抽象化インターフェイスとInMemoryDataContextがあります。
InMemoryプロバイダーはEF7(プレリリース)に含まれています。
NuGetパッケージ を使用するか、GitHubの EFリポジトリ ( ソースの表示 )でそれについて読むことができます。
記事 http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort 説明 Effort -EntityFrameworkプロバイダーメモリ内で実行されます。
実際のデータベースがなくても、単体テスト内でDbContextクラスまたはObjectContextクラスを引き続き使用できます。
ここでのより良いアプローチは、リポジトリパターンを使用してEFコードをカプセル化することです。サービスをテストするときは、モックまたは偽物を使用できます。リポジトリをテストするときは、実際のDBにアクセスして、期待する結果が得られていることを確認する必要があります。
はい、そのようなプロバイダーは少なくとも1つあります SQLite 。私はそれを少し使用しました、そしてそれは働きます。また、 SQL Server Compact を試すこともできます。これは埋め込みデータベースであり、EFプロバイダーもあります。
編集:
SQLiteはインメモリデータベースをサポートしています( link1 )。必要なのは、「Data Source =:memory :; Version = 3; New = True;」のような接続文字列を指定することだけです。例で必要な場合は、 SharpArchitecture を参照してください。
私はEntityFrameworkとObjectQueryクラスに精通していませんが、Includeメソッドが仮想の場合は、次のようにモックできます。
// Arrange
var customerSourceStub = MockRepository.GenerateStub<ObjectQuery<Customer>>();
var customers = new Customer[]
{
// Populate your customers as if they were coming from DB
};
customerSourceStub
.Stub(x => x.Include("Order"))
.Return(customers);
var sut = new CustomerService(customerSourceStub);
// Act
var actual = sut.GetCustomerById(5);
// Assert
Assert.IsNotNull(actual);
Assert.AreEqual(5, actual.Id);
SQL Server Compact を試すこともできますが、かなり大きな制限があります。
EF Core では、これを行うための2つの主なオプションがあります。
私はSQLiteを使用しており、AzureSQL本番データベースで行う必要のあるすべてのクエリをサポートしています。