开发者

Integration Testing Entity Framework code first with in-memory database

I'd like to run actual integration tests of my EF4.1 repositories against an in-memory database a la ayende's nhibernate version.

I have a code first model, against a legacy database (old table and column names need mapping to my entites using code configurations).

I'd like to be able to use Sqlite (or oth开发者_运维百科er) to:

  1. Generate an in-memory database from my model
  2. Create a DBContext for my model with this in-memory database
  3. I have already in place IoC/DI of a IDBContextFactory which gets constructed with my (Generic) Repositories (also using a GenericRepository pattern)

There's bits and bobs on-line which suggest it should be possible, but not much for code-first approaches. Anyone know if this is possible?

Some snippets of my test library, see // THROWS ERROR marking runtime errors:

public class MyDbContextFactory : IDbContextFactory
  {
    private static object context;
    public object CurrentContext
    {
      get {
        if(context == null)
        {
          // ?? DOESN'T WORK AS THERE'S NO META DATA
          var connBuilder = new EntityConnectionStringBuilder();
          connBuilder.Provider = "System.Data.SQLite";
          connBuilder.Metadata = 
           @"res://*/TestEfDb.csdl|res://*/TestEfDb.ssdl|res://*/TestEfDb.msl";
          connBuilder.ProviderConnectionString = 
           ConfigurationManager.ConnectionStrings["DataContext"].Name;

          var entConnection = new EntityConnection(connBuilder.ConnectionString);

          // THROWS ERROR: sqlite Format of the initialization string does not
          // conform to specification starting at index 0
          // for connection string "Data Source=:memory:;Version=3;New=True;"

          //var entConnection = new EntityConnection
          // (ConfigurationManager.ConnectionStrings["DataContext"].Name);
          context = new MyDbContext(entConnection);
        }
        return context;
      }
    }
  }

...

 [Test]
    public void test_me()
    {
        var auditRespository = new AuditRepository(new MyDbContextFactory());
        auditRespository.GetAll<Audit>();
    }


Use SQL Compact 4.0 (download both SqlCE and tools by web platform installer) - EF Code first has direct support for that. The only difference will be that your application will use connection string to big SQL Server:

<add name="MyDbContext" 
     provider="System.Data.SqlClient" 
     connectionString=
       "Data Source=...;InitialCatalog=...;Integrated Security=SSPI" />

and your tests will use connection string to SQL Compact:

<add name="MyDbContext" 
     provider="System.Data.SqlServerCe.4.0" 
     connectionString="Data Source=Database.sdf" />


Take a look at this article: Faking your LINQ provider. It describes how you can hide Entity Framework behind an abstraction, so that you can easily unit test your application, while still allowing to use LINQ (over IQueryable) queries against it in your application code.

Note that this does not completely remove the need of writing integration tests, since you would still need to test the database mapping layer and possibly test whether the chosen LINQ provider is able to execute the LINQ queries.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜