Is there an in-memory provider for Entity Framewor

2019-01-14 14:56发布

I am unit testing code written against the ADO .NET Entity Framework. I would like to populate an in-memory database with rows, and make sure that my code retrieves them properly.

I can mock the Entity Framework using Rhino Mocks, but that would not be sufficient. I would be telling the query what entities to return to me. This would neither test the where clause nor the .Include() statements. I want to be sure that my where clause matches only the rows I intend, and no others. I want to be sure that I have asked for the entities that I need, and none that I don't.

For example:

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();
    }
}

If I mock the ObjectQuery to return a known customer populated with orders, how do I know that CustomerService has the right where clause and Include? I would rather insert some customer rows and some order rows, then assert that the right customer was selected and the orders are populated.

8条回答
Juvenile、少年°
2楼-- · 2019-01-14 15:23

The article http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort  describes Effort  -Entity Framework provider that runs in memory.

You can still use your DbContext or ObjectContext classes within unit tests, without having to have an actual database.

查看更多
时光不老,我们不散
3楼-- · 2019-01-14 15:26

Yes, there is at least one such provider - SQLite. I have used it a bit and it works. Also you can try SQL Server Compact. It's an embeded database and has EF providers too.
Edit:
SQLite has support for in-memory databases (link1). All you need is to specify a connection string like: "Data Source=:memory:;Version=3;New=True;". If you need in an example you may look at SharpArchitecture.

查看更多
ら.Afraid
4楼-- · 2019-01-14 15:30

There is not currently a in memory provider for EF, but if you take a look at Highway.Data it has a base abstraction interface and an InMemoryDataContext.

Testing Data Access and EF with Highway.Data

查看更多
趁早两清
5楼-- · 2019-01-14 15:30

An InMemory provider is included in EF7 (pre-release).

You can use either the NuGet package, or read about it in the EF repo on GitHub (view source).

查看更多
聊天终结者
6楼-- · 2019-01-14 15:30

I am not familiar with Entity Framework and the ObjectQuery class but if the Include method is virtual you can mock it like this:

// 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);
查看更多
兄弟一词,经得起流年.
7楼-- · 2019-01-14 15:39

You could try SQL Server Compact but it has some quite wild limitations:

  • SQL Server Compact does not support SKIP expressions in paging queries when it is used with the Entity Framework
  • SQL Server Compact does not support entities with server-generated keys or values when it is used with the Entity Framework
  • No outer joins, collate, modulo on floats, aggregates
查看更多
登录 后发表回答