scott-xu / EntityFramework.Testing

EntityFramework Testing
Apache License 2.0
102 stars 26 forks source link

EntityFramework.Testing NuGet Version Build status

EntityFramework.Testing provides an implementation of DbAsyncQueryProvider that can be used when testing a component that uses async queries with EntityFramework.

The project is cut from EntityFrameworks' source code. Some changes are made to be compliant with StyleCop/CodeAnalysis

All the following mocked DbSet operations work as expected:

The following samples are based on this Controller:

public class BlogsController : Controller
{
    private readonly BloggingContext db;

    public BlogsController(BloggingContext context)
    {
        db = context;
    }

    public async Task<ViewResult> Index()
    {
        var query = db.Blogs.OrderBy(b => b.Name);

        return View(await query.ToListAsync());
    }
}

EntityFramework.Testing.Moq NuGet Version

EntityFramework.Testing.Moq provides a helpful extension method to mock EntityFramework's DbSets using Moq.

You can write a unit test against a mock context as follows. SetupData extension method is part of EntityFramework.Testing.Moq.

[TestMethod]
public async Task Index_returns_blogs_ordered_by_name()
{
    // Create some test data
    var data = new List<Blog>
    {
        new Blog{ Name = "BBB" },
        new Blog{ Name = "CCC" },
        new Blog{ Name = "AAA" }
    };

    // Create a mock set and context
    var set = new Mock<DbSet<Blog>>()
        .SetupData(data);

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

    // Create a BlogsController and invoke the Index action
    var controller = new BlogsController(context.Object);
    var result = await controller.Index();

    // Check the results
    var blogs = (List<Blog>)result.Model;
    Assert.AreEqual(3, blogs.Count());
    Assert.AreEqual("AAA", blogs[0].Name);
    Assert.AreEqual("BBB", blogs[1].Name);
    Assert.AreEqual("CCC", blogs[2].Name);
}

EntityFramework.Testing.Moq.Ninject NuGet Version

EntityFramework.Testing.Moq.Ninject provides a Ninject Module to auto mock DbContext and its DbSet<> properties using Ninject.MockingKernel.Moq.

[TestMethod]
public async Task Index_returns_blogs_ordered_by_name()
{
    using (var kernel = new MoqMockingKernel())
    {
        kernel.Load(new EntityFrameworkTestingMoqModule());

        // Create some test data
        var data = new List<Blog>
        {
            new Blog{ Name = "BBB" },
            new Blog{ Name = "CCC" },
            new Blog{ Name = "AAA" }
        };

        // Setup mock set
        kernel.GetMock<DbSet<Blog>>()
            .SetupData(data);

        // Get a BlogsController and invoke the Index action
        var controller = kernel.Get<BlogsController>();
        var result = await controller.Index();

        // Check the results
        var blogs = (List<Blog>)result.Model;
        Assert.AreEqual(3, blogs.Count());
        Assert.AreEqual("AAA", blogs[0].Name);
        Assert.AreEqual("BBB", blogs[1].Name);
        Assert.AreEqual("CCC", blogs[2].Name);
    }
}

EntityFramework.Testing.NSubstitute NuGet Version

EntityFramework.Testing.NSubstitute provides a helpful extension method to mock EntityFramework's DbSets using NSubstitute.

You can write a unit test against a mock context as follows. SetupData extension method is part of EntityFramework.Testing.NSubstitute.

[TestMethod]
public async Task Index_returns_blogs_ordered_by_name()
{
    // Create some test data
    var data = new List<Blog>
    {
        new Blog{ Name = "BBB" },
        new Blog{ Name = "CCC" },
        new Blog{ Name = "AAA" }
    };

    // Create a DbSet substitute.
    var set = Substitute.For<DbSet<Blog>, IQueryable<Blog>, IDbAsyncEnumerable<Blog>>()
                        .SetupData(data);

    var context = Substitute.For<BloggingContext>();
    context.Blogs.Returns(set);

    // Create a BlogsController and invoke the Index action
    var controller = new BlogsController(context);
    var result = await controller.Index();

    // Check the results
    var blogs = (List<Blog>)result.Model;
    Assert.AreEqual(3, blogs.Count());
    Assert.AreEqual("AAA", blogs[0].Name);
    Assert.AreEqual("BBB", blogs[1].Name);
    Assert.AreEqual("CCC", blogs[2].Name);
}

EntityFramework.Testing.NSubstitute.Ninject NuGet Version

EntityFramework.Testing.NSubstitute.Ninject provides a Ninject Module to auto mock DbContext and its DbSet<> properties using Ninject.MockingKernel.NSubstitute.

[TestMethod]
public async Task Index_returns_blogs_ordered_by_name()
{
    using (var kernel = new NSubstituteMockingKernel())
    {
        kernel.Load(new EntityFrameworkTestingNSubstituteModule());

        // Create some test data
        var data = new List<Blog>
        {
            new Blog{ Name = "BBB" },
            new Blog{ Name = "CCC" },
            new Blog{ Name = "AAA" }
        };

        // Setup mock set
        kernel.Get<DbSet<Blog>>()
            .SetupData(data);

        // Get a BlogsController and invoke the Index action
        var controller = kernel.Get<BlogsController>();
        var result = await controller.Index();

        // Check the results
        var blogs = (List<Blog>)result.Model;
        Assert.AreEqual(3, blogs.Count());
        Assert.AreEqual("AAA", blogs[0].Name);
        Assert.AreEqual("BBB", blogs[1].Name);
        Assert.AreEqual("CCC", blogs[2].Name);
    }
}

EntityFramework.Testing.FakeItEasy NuGet Version

EntityFramework.Testing.FakeItEasy provides a helpful extension method to mock EntityFramework's DbSets using FakeItEasy.

You can write a unit test against a mock context as follows. SetupData extension method is part of EntityFramework.Testing.FakeItEasy.

[TestMethod]
public async Task Index_returns_blogs_ordered_by_name()
{
    // Create some test data
    var data = new List<Blog>
    {
        new Blog{ Name = "BBB" },
        new Blog{ Name = "CCC" },
        new Blog{ Name = "AAA" }
    };

    // Create a DbSet substitute.
    var set = A.Fake<DbSet<Blog>>(o => o.Implements(typeof(IQueryable<Blog>)).Implements(typeof(IDbAsyncEnumerable<Blog>)))
                        .SetupData(data);

    var context = A.Fake<BloggingContext>();
    context.Blogs.Returns(set);

    // Create a BlogsController and invoke the Index action
    var controller = new BlogsController(context);
    var result = await controller.Index();

    // Check the results
    var blogs = (List<Blog>)result.Model;
    Assert.AreEqual(3, blogs.Count());
    Assert.AreEqual("AAA", blogs[0].Name);
    Assert.AreEqual("BBB", blogs[1].Name);
    Assert.AreEqual("CCC", blogs[2].Name);
}

EntityFramework.Testing.FakeItEasy.Ninject NuGet Version

EntityFramework.Testing.FakeItEasy.Ninject provides a Ninject Module to auto mock DbContext and its DbSet<> properties using Ninject.MockingKernel.FakeItEasy.

[TestMethod]
public async Task Index_returns_blogs_ordered_by_name()
{
    using (var kernel = new FakeItEasyMockingKernel())
    {
        kernel.Load(new EntityFrameworkTestingFakeItEasyModule());

        // Create some test data
        var data = new List<Blog>
        {
            new Blog{ Name = "BBB" },
            new Blog{ Name = "CCC" },
            new Blog{ Name = "AAA" }
        };

        // Setup mock set
        kernel.Get<DbSet<Blog>>()
            .SetupData(data);

        // Get a BlogsController and invoke the Index action
        var controller = kernel.Get<BlogsController>();
        var result = await controller.Index();

        // Check the results
        var blogs = (List<Blog>)result.Model;
        Assert.AreEqual(3, blogs.Count());
        Assert.AreEqual("AAA", blogs[0].Name);
        Assert.AreEqual("BBB", blogs[1].Name);
        Assert.AreEqual("CCC", blogs[2].Name);
    }
}