ASP.NET MVC 5 Ninject

Mocking Entity Framework DBSet objects using Moq

Unit testing in .NET is pretty nice when your dependency injection/IoC is setup well, but Entity Framework 6 isn’t the nicest framework for mocking and testing. If you’re using ASP.NET MVC 5, you may have run in to this scenario.

Problem: You want to use or mock a DbSet

So you have an IEnumerable (list, array, etc) that you want to use on your tests, but your DbContext only has DbSets. Unfortunately, the DbSet constructor is protected, so you can’t just ‘new’ one up. The solution is our friend Moq.

Solution

This handy IEnumerable extension will give you back a DBSet with your IEnumerable in the data. Now you can mock out your DbContext properties or result sets however you wish! You probably want to leave callBase as true so the base implementation is called when you haven’t set up certain properties, but if you’re having problems, maybe try setting callBase to false.

public static class TestingExtensions
{
    private static Mock<DbSet<T>> AsMockDbSet<T>(IEnumerable<T> data, bool callBase = true) where T : class
    {
        var mockSet = new Mock<DbSet<T>>();
        var queryable = data.AsQueryable();

        mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
        mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
        mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
        mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());

        mockSet.CallBase = callBase;

        return mockSet;
    }
}

Problems? Questions? Did I save you some time? Let me know on Twitter @kerryritter.

Leave a Reply

Your email address will not be published. Required fields are marked *