How to Mock an Entity Framework DbContext and DbSet with Moq

If you find yourself in a situation where you need to mock a DbContext and DbSet with the Moq framework, it is easy to do. However, there are a couple of “gotchas” I found out recently.

Let’s assume the following simplified MyEntity, MyEntityRepository, and MyDbContext classes:

    public class MyEntity
    {
        public string Name { get; set; }
    }

    // Provides a repository for MyEntity objects.
    public class MyEntityRepository
    {
        private Func<MyDbContext> createContext;

        // Initializes a new instance of the MyEntityRepository class using
        // the specified DbContext factory method.
        public MyEntityRepository(Func<MyDbContext> createContext)
        {
            this.createContext = createContext;
        }

        // Gets all the entities with the specified name.
        public IEnumerable<MyEntity> GetMyEntities(string name)
        {
            using (var context = this.createContext())
            {
                return context.MyEntities
                    .Where(myEntity => myEntity.Name == name)
                    .ToArray();
            }
        }
    }

    public class MyDbContext : DbContext
    {
        public virtual DbSet<MyEntity> MyEntities { get; set; }
    }

We want to write a unit test for the MyEntityRepository.GetMyEntities(string name) method, to ensure it is filtering entities correctly. We can accomplish this with a test method that looks similar to the following:

        // Tests that the MyEntityRepository can get entities by a name.
        [TestMethod]
        public void CanGetEntitiesByAName()
        {
            // Initialize a list of MyEntity objects to back the DbSet with.
            var myEntities = new List<MyEntity>()
            {
                new MyEntity() { Name = "Entity1" },
                new MyEntity() { Name = "Entity1" },
                new MyEntity() { Name = "Entity2" }
            };

            // Create a mock DbContext.
            var dbContext = new Mock<MyDbContext>();

            // Create a mock DbSet.
            var dbSet = new Mock<DbSet<MyEntity>>();

            // Set up the MyEntities property so it returns the mocked DbSet.
            dbContext.Setup(o => o.MyEntities).Returns(dbSet.Object);

            // Set up the DbSet as an IQueryable so it can be enumerated.
            var queryable = myEntities.AsQueryable();
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.Provider).Returns(queryable.Provider);
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.Expression).Returns(queryable.Expression);
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());

            var uut = new MyEntityRepository(() => dbContext.Object);
            var results = uut.GetMyEntities("Entity1");

            Assert.AreEqual(2, results.Count());
        }

Seems pretty straightforward, but it doesn’t work. When ran in the test runner, you are presented with this error:

Test method CodingOnCaffeine.MyEntityRepositoryTests.CanGetEntitiesByAName threw exception: 
System.NotImplementedException: The member 'IQueryable.Provider' has not been implemented on type 'DbSet`1Proxy' which inherits from 'DbSet`1'. Test doubles for 'DbSet`1' must provide implementations of methods and properties that are used.

Because of the way Moq’s underlying proxies work, the IQueryable methods and property set ups never made it on the underlying Mock proxy exposed by the MyDbContext.MyEntities property. We can address this by simply using a lambda expression when we set up the MyDbContext.MyEntities property.

        // Tests that the MyEntityRepository can get entities by a name.
        [TestMethod]
        public void CanGetEntitiesByAName()
        {
            // Initialize a list of MyEntity objects to back the DbSet with.
            var myEntities = new List<MyEntity>()
            {
                new MyEntity() { Name = "Entity1" },
                new MyEntity() { Name = "Entity1" },
                new MyEntity() { Name = "Entity2" }
            };

            // Create a mock DbContext.
            var dbContext = new Mock<MyDbContext>();

            // Create a mock DbSet.
            var dbSet = new Mock<DbSet<MyEntity>>();

            // Set up the MyEntities property so it returns the mocked DbSet.
            dbContext.Setup(o => o.MyEntities).Returns(() => dbSet.Object);

            // Set up the DbSet as an IQueryable so it can be enumerated.
            var queryable = myEntities.AsQueryable();
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.Provider).Returns(queryable.Provider);
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.Expression).Returns(queryable.Expression);
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
            dbSet.As<IQueryable<MyEntity>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());

            var uut = new MyEntityRepository(() => dbContext.Object);
            var results = uut.GetMyEntities("Entity1");

            Assert.AreEqual(2, results.Count());
        }

The test passes now since the IQueryable methods and properties are set up correctly on the underlying proxy, and the proxy is reevaluated by the lambda expression when the MyDbContext.MyEntities is accessed in the test.

With such a complex set up for a mock DbSet, this code could be refactored to be a little more reusable. Let’s create a factory to help with this.

    // Provides a way to create mock DbSets
    public static class MockDbSetFactory
    {
        // Creates a mock DbSet from the specified data.
        public static Mock<DbSet<T>> Create<T>(IEnumerable<T> data) where T : class
        {
            var queryable = data.AsQueryable();
            var mock = new Mock<DbSet<T>>();
            mock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
            mock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
            mock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
            mock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());

            return mock;
        }
    }

With this factory, the test looks much easier to read. It also alleviates the need to use a lambda expression in the Returns() method setup on the MyDbContext mock, since the mock DbSet is fully created in a single function call.

        // Tests that the MyEntityRepository can get entities by a name.
        [TestMethod]
        public void CanGetEntitiesByAName()
        {
            // Initialize a list of MyEntity objects to back the DbSet with.
            var myEntities = new List<MyEntity>()
            {
                new MyEntity() { Name = "Entity1" },
                new MyEntity() { Name = "Entity1" },
                new MyEntity() { Name = "Entity2" }
            };

            // Create a mock DbContext.
            var dbContext = new Mock<MyDbContext>();

            // Create a mock DbSet.
            var dbSet = MockDbSetFactory.Create(myEntities);

            // Set up the MyEntities property so it returns the mocked DbSet.
            dbContext.Setup(o => o.MyEntities).Returns(dbSet.Object);

            var uut = new MyEntityRepository(() => dbContext.Object);
            var results = uut.GetMyEntities("Entity1");

            Assert.AreEqual(2, results.Count());
        }

Hopefully after reading this you guys won’t be spinning your wheels as long as I did trying to figure out why your mock DbSet wasn’t being set up, even though you thought it was. Cheers.

How to Break Out Aggregate Roots and Repositories in a Legacy Entity Framework Application

I started working at my current job about a year ago. They are a bright group, filled with a diverse set of development talent. The applications our team works on are multi-tiered with extremely complex business logic, a DDD enthusiast’s heaven. However, one of the first things I noticed when I got on board with this team was that the data access layer classes were non-standardized, and contained some business logic.

Most of us by now have seen the Repository Pattern in practice, or have at least read or watched a video on it and its usefulness in and outside of Domain Driven Design. Most of the situations in these videos are contrived in a sense that the developers are starting a project from scratch, and have the option to bake in the Entity Framework into the actual core domain objects using EF Code First. This approach is elegant and definitely cuts down on the amount of code required to persist domain objects in repositories, but implementing it in legacy applications requires quite a bit of changes, both in the database and the client application’s code. The approach we took was to keep our current EF classes intact, continue to use them as part of the repository’s implementation details, and redefine the core domain objects coming out of the repositories.

Continue reading