web-dev-qa-db-ja.com

Entity Frameworkのインメモリプロバイダーはありますか?

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があることをどのように知ることができますか?むしろ、いくつかの顧客行といくつかの注文行を挿入してから、適切な顧客が選択され、注文が入力されていることを表明します。

38
Michael L Perry

現在、EFのメモリ内プロバイダーはありませんが、Highway.Dataを見ると、基本の抽象化インターフェイスとInMemoryDataContextがあります。

Highway.Dataを使用したデータアクセスとEFのテスト

7
Devlin Liles

InMemoryプロバイダーはEF7(プレリリース)に含まれています。

NuGetパッケージ を使用するか、GitHubの EFリポジトリソースの表示 )でそれについて読むことができます。

16
Shimmy

記事 http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort 説明 Effort -EntityFrameworkプロバイダーメモリ内で実行されます。

実際のデータベースがなくても、単体テスト内でDbContextクラスまたはObjectContextクラスを引き続き使用できます。

ここでのより良いアプローチは、リポジトリパターンを使用してEFコードをカプセル化することです。サービスをテストするときは、モックまたは偽物を使用できます。リポジトリをテストするときは、実際のDBにアクセスして、期待する結果が得られていることを確認する必要があります。

9
Andrew Peters

はい、そのようなプロバイダーは少なくとも1つあります SQLite 。私はそれを少し使用しました、そしてそれは働きます。また、 SQL Server Compact を試すこともできます。これは埋め込みデータベースであり、EFプロバイダーもあります。
編集:
SQLiteはインメモリデータベースをサポートしています( link1 )。必要なのは、「Data Source =:memory :; Version = 3; New = True;」のような接続文字列を指定することだけです。例で必要な場合は、 SharpArchitecture を参照してください。

6
zihotki

私は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);
2
Darin Dimitrov

SQL Server Compact を試すこともできますが、かなり大きな制限があります。

  • SQL Server Compactは、Entity Frameworkで使用される場合、ページングクエリでSKIP式をサポートしません。
  • SQL Server Compactは、Entity Frameworkで使用される場合、サーバーで生成されたキーまたは値を持つエンティティをサポートしません。
  • 外部結合、照合、フロートのモジュロ、集計はありません
1
Chris S

EF Core では、これを行うための2つの主なオプションがあります。

  1. SQLiteインメモリモード は、リレーショナルデータベースのように動作するプロバイダーに対して効率的なテストを作成できます。
  2. InMemoryプロバイダー は、依存関係が最小限の軽量プロバイダーですが、常にリレーショナルデータベースのように動作するとは限りません。

私はSQLiteを使用しており、AzureSQL本番データベースで行う必要のあるすべてのクエリをサポートしています。