Click here to Skip to main content
15,918,889 members
Articles / Programming Languages / C#

Using FakeItEasy with Entity Framework 6

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
7 Dec 2017CPOL4 min read 10.9K   7   2
How to use FakeItEasy with Entity Framework 6

What This Article is About

I have quickly become a fan of FakeItEasy. If you are not familiar with it, visit and check out the super fluent interface yourself.

I couldn’t resist looking for a way to quickly fake out EF6 and I am going to share how that went.

What I Will Not Be Discussing

  • The differences between mocks, stubs and so on (see Gerard Meszaro‘s list for that)
  • The usefulness of mocking ORMs
  • The limitations of in-memory test doubles for a database

Background – Testing with EF5

In EF5 (before my time!), we would create a mock DbSet class that implemented IDbSet, with a whole load of properties and methods. Then, create an interface for a DbContext and implement that with a mocked context. I did this following the instructions here and it generated quite a lot of code to maintain for my relatively small project.

Changes in EF6

In EF6, DbSet gained an additional protected internal constructor. So, instead of creating all those mocks, we mark the DbSet properties virtual, allowing FakeItEasy to override them:

public virtual DbSet<Product> Products { get; set; }

Working with the DbSet Methods

This is fairly straightforward and requires the behaviour of any DbSet method called to be defined.

Create instances of a fake context and fake DbSet, arrange the behaviour for calls to the Products getter and calls to the Add method on the DbSet:

var fakeContext = A.Fake<ApplicationDbContext>();
var fakeDbSet = A.Fake<DbSet<Product>>();
A.CallTo(() => mockContext.Products).Returns(fakeDbSet);
A.CallTo(() => fakeDbSet.Add(A<Product>.Ignored)).Returns(fakeProduct);

Why not setup calls directly to the methods given as we need to define their behaviour individually?

A.CallTo(() => fakeContext.Products.Add(A<Product>.Ignored)).Returns(fakeProduct);

We can but I prefer the first way as it has clearer logic and keeps things consistent with the way we can work with LINQ extension methods below. Opinions?

Note that there is no difference in arrangement between DbSet’s asynchronous and non-asynchronous methods.

Working with the LINQ Extension Methods (Non-asynchronously)

So what if the method under test is using LINQ extension methods on the DbSet?

_dbContext.Products.Where(p => p.Id == 2).Select(d => new...

On the face of it, these are tidier to work with because after setting up your fake DbSet, LINQ-to-Objects kicks in and there is no need to identify the behaviour of individual methods. We will take advantage of DbSet implementing IQueryable:

public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>,
        IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable
where TEntity : class

For our in-memory storage, we will use a List that implements IQueryable, which allows us to return its properties and method to use in the fake DbSet.

IQueryable<Product> fakeIQueryable =
      new List<Product>().AsQueryable();

Next, we setup the fake DbSet. Note that FakeItEasy needs to be told explicitly to implement IQueryable in order for the Castle proxy to intercept.

var fakeDbSet = A.Fake<DbSet<Product>>( (d => d

To setup the behaviour for the DbSet under LINQ methods, we can ‘redirect’ all calls to the method and properties of the IQueryable interface to the fakeIQueryable.

A.CallTo(() => ((IQueryable<Product>)fakeDbSet).GetEnumerator())
  .Returns(fakeIQueryable .GetEnumerator());
A.CallTo(() => ((IQueryable<Product>)fakeDbSet).Provider)
  .Returns(fakeIQueryable .Provider);
A.CallTo(() => ((IQueryable<Product>)fakeDbSet).Expression)
  .Returns(fakeIQueryable .Expression);
A.CallTo(() => ((IQueryable<Product>)fakeDbSet).ElementType)
  .Returns(fakeIQueryable .ElementType);

Finally, we setup the fake context and its behaviour when the Products DbSet getter is called; then go ahead and instantiate the object under test, passing it the fake context and a dummy to the Get method.

var fakeContext = A.Fake<ApplicationDbContext>();
A.CallTo(() => fakeContext.Products).Returns(fakeDbSet);
var productRepository = new ProductRepository(fakeContext);
var results = productRepository.Get(A<int>.Ignored);

Working with the LINQ Extension Methods (Asynchronously)

Problem 1: What if we used a similar test arrangement for a test method that calls an asynchronous LINQ extension method? e.g.

await _dbContext.Products.SingleOrDefaultAsync(e => e.Id == id);

We get an error: The provider for the source IQueryable does not implement IDbAsyncQueryProvider

So here, we must change our behaviour for the Provider property. I have made use of a class provided by MSDN that wraps up our fakeIQueryable to provide an implementation of IDbAsyncQueryProvider:

await _dbContext.Products.SingleOrDefaultAsync(e => e.Id == id);
                A.CallTo(() => ((IQueryable<Product>)fakeDbSet).Provider)
               .Returns(new TestDbAsyncQueryProvider<Product>( fakeIQueryable.Provider));

Problem 2: What if we want to enumerate through the DbSet asynchronously?

IEnumerable<Product> products = await _dbContext.Products.ToListAsync();

We’ll get a different error message, and the solution here is to use another class provided in the link above to wrap up our fakeIQueryable to implement IDbAsyncEnumerator, replacing the original call to GetEnumerator form earlier.

A.CallTo(() => ((IDbAsyncEnumerable<Product>)fakeDbSet).GetAsyncEnumerator())
         .Returns(new TestDbAsyncEnumerator<Product>(mockIQueryable.GetEnumerator()));

FakeItEasy now also needs to be told to implement IDbAsyncEnumerable.

var fakeDbSet = A.Fake<DbSet<Product>>(d => d


I did not have time to look at FakeItEasy and EF’s validation in depth.

I briefly considered one scenario where we might be relying on EF for our data validation, catching any DbEntityValidationException. We could quite easily check how our code handles validation errors by throwing a DbEntityValidationException, e.g.

A.CallTo(() => mockContext.SaveChangesAsync()).Throws(new DbEntityValidationException());

Then construct an IEnumerable of DbEntityValidationResult. However, this is just theory and I have not tried this myself yet!


If you are already using FakeItEasy in your tests, it is quite nice for consistency to be able to use it with Entity Framework without having to maintain mock code for DbContext and DbSet.

There are obvious limitations to how much behaviour can be faked this way. I did say I would not be debating the merits of mocking an ORM but here are just two issues with mocking EF:

  • The differences in behaviour between LINQ-to-Objects and LINQ-to-Entities are many – there is a good answer here detailing some of these
  • Mocking the behaviour of EF’s validation would likely be unmanageable

I would be interested in hearing others’ experiences of scenarios where it has been useful to mock EF.

Other Options

There are a few other efforts (get the reference?) out there to provide support for testing EF but they are often poorly maintained. Highway.Data looks interesting but I have not tried it yet (link).

.NET Core now has an InMemory provider for testing (link).


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Software Developer (Senior)
United Kingdom United Kingdom
Ben is the Principal Developer at a and .NET Foundation foundation member. He previously worked for over 9 years as a school teacher, teaching programming and Computer Science. He enjoys making complex topics accessible and practical for busy developers.

Comments and Discussions

GeneralWill try... Pin
Ben Hall ( 8:48
professionalBen Hall ( 8:48 
Questionplease upload the full code Pin
Mou_kol7-Dec-17 23:51
Mou_kol7-Dec-17 23:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.