Easier Mocking of EntityFramework DBSets: EntityFramework.Testing


If you have an application that uses EntityFramework, and you are writing unit tests for this application, you will probably benefit from mocking EF. For example, this will allow you to run your unit tests without actually connecting it to a database and can be very useful if you run your unit tests on a build server.

Here is a typical example of setting up mocking using Moq.

First, our sample DBContext and DBSet:

// our db context
public class ShopDBContext : DbContext
{
  public DbSet<Customer> Customers { get; set; }
}

Here is the usual setting up of sample data:

// create a list and fill with test data
var testCustomers = new List<Customer>();
testCustomers.Add(new Customer()); // etc.

And now the mocking:

// setup the mock db context
var mockContext = new Mock<MyDbContext>();

// create the mock dbset
var mockCustomers = new Mock<DbSet<Customer>>();

// get a queryable of our test data
var testCustomersQueryable = testCustomers.AsQueryable();

// setup the mock dbset
mockCustomers.As<IQueryable<T>>().Setup(m => m.Provider).Returns(testCustomersQueryable.Provider);
mockCustomers.As<IQueryable<T>>().Setup(m => m.Expression).Returns(testCustomersQueryable.Expression);
mockCustomers.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(testCustomersQueryable.ElementType);
mockCustomers.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => testCustomersQueryable.GetEnumerator());

// tell the mock context to return the mock dbset
mockContext.Setup(m => m.Customers).Returns(mockCustomers.Object);

As you can see there is quite a bit of boilerplate code that we may end up repeating if we are mocking a lot of DBSets…

Fortunately, there is a library available which allows us to simplify our code (the mocking portion anyway) into this:

// setup the mock db context
var mockContext = new Mock<MyDbContext>();

// setup the mock dbset
var set = new Mock<DbSet<Customer>>().SetupData(testCustomers);

// tell the mock context to return the mock dbset
mockContext.Setup(m => m.Customers).Returns(mockCustomers.Object);

The library is EntityFramework.Testing, and it works with Moq, Nsubstitute, and FakeItEasy. It is available both on GitHub and as an assortment of Nuget packages, here is the one we used with Moq: https://www.nuget.org/packages/EntityFrameworkTesting.Moq/

 

LTN Software provides professional web, desktop, and mobile software development and consulting services.


Tags: , ,