Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Testing with mock on Entity Framework 6

0.00/5 (No votes)
31 Oct 2015 1  
EntityFramework.MoqHelper library to work with Entity Framework 6 and Moq libraries doing mocks of Entity Framework main methods that access database.

Introduction

EntityFramework.MoqHelper is a simple library, but a lot of help when it comes to mock with Entity Framework.

To create objects through mock, it needs to perform many settings, especially for test scenarios where queries are made.

Many of these codes required were encapsulated in that library and some logic to work with lists of objects and queries were made. Using a fluent interface, you can perform different settings to mock DbContext and DbSet objects.

To mock EF objects, the library was chosen to Moq (https://github.com/Moq/moq4) because it is a stable and very popular library of Mock in general.

The focus of this library is to facilitate the developer's life when testing using EF without accessing the database directly.

Background

In Entity Framework 6, many improvements have been made, including test scenarios, it is now possible to make mock of the main methods used for reading and writing to the database.

To understand in more detail what it was and how it was improved with focus on mocks suggest a reading of the post of Julie Lerman "How EF6 Enables Mocking DbSets more easily" which can be accessed below:

For a more practical view, I suggest reading the post "Testing with a mocking framework (EF6 onwards)", is also important for those who are not yet familiar with mocks the EF.

Using the Code

This is a simple query scenario, taken from one of the references cited in the "Background" section important to understand how the mock and the settings are made on DbContext and DbSet objects.

[TestClass]
public class QueryTests
{
    [TestMethod]
    public void GetAllBlogs_orders_by_name()
    {
        var data = new List<Blog>
        {
            new Blog { Name = "BBB" },
            new Blog { Name = "ZZZ" },
            new Blog { Name = "AAA" },
        }.AsQueryable();

        var mockSet = new Mock<DbSet<Blog>>();
        mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider);
        mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
        mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
        mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

        var mockContext = new Mock<BloggingContext>();
        mockContext.Setup(c => c.Blogs).Returns(mockSet.Object);

        var service = new BlogService(mockContext.Object);
        var blogs = service.GetAllBlogs();

        Assert.AreEqual(3, blogs.Count);
        Assert.AreEqual("AAA", blogs[0].Name);
        Assert.AreEqual("BBB", blogs[1].Name);
        Assert.AreEqual("ZZZ", blogs[2].Name);
    }
}

Pay attention to required settings that are made in the implementation of IQueryable and DbSet (the mock settings related to the class being tested) and in the application DbContext.

All of this code is still necessary and they were encapsulated using fluent interface. The code listed above is a lot verbose, in this method we have more code referent to settings the mock instead of business rules that were tested and things only gets worse when we add in this scenario inserts, updates and deletions of items.

You must configure each Entity Framework method related to each operation you want to make the database available in DbSet as DbSet.Add, DbSet.Find and DbSet.Remove, for example.

Using this library, it can make it through something like:

var customers = new List<Customer>();
var mockSet = EntityFrameworkMoqHelper.CreateMockForDbSet<Customer>()
                                                .SetupForQueryOn(customers)
                                                .WithAdd(customers, "CustomerID")
                                                .WithFind(customers, "CustomerID")
                                                .WithRemove(customers);

To see a more complex sample of how to use this library, you can take a look at my project on github referenced below:

To install as nuget package, run the following command in the Package Manager Console:

Install-Package EntityFramework.MoqHelper

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here