Click here to Skip to main content
15,887,683 members
Articles / Programming Languages / C#
Tip/Trick

Testing with mock on Entity Framework 6

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
31 Oct 2015CPOL2 min read 39K   14   3
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.

C#
[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:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Brazil Brazil
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWoW Pin
Celton Borges4-May-16 4:21
Celton Borges4-May-16 4:21 
AnswerRe: WoW Pin
Richard Silveira4-May-16 15:05
Richard Silveira4-May-16 15:05 
SuggestionFor NSubstitute use... Pin
Chris at M2-Nov-15 16:20
Chris at M2-Nov-15 16:20 

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.