模拟实体DbContext插入

时间:2018-03-07 15:37:39

标签: c# unit-testing entity-framework-6 moq xunit

我正在使用 Xunit &的起订量即可。我希望能够在表格中模拟插入。这样,记录实际上不会填充表,但单元测试可以验证插入是否成功。使用真正的DbContext,单元测试适用于下面的方法 Add_Works()。当我尝试使用Mock时,在 Add_WantToWork()中,我收到错误,“对象引用未设置为对象的实例”。失败发生在 Context.Set()。在 ARepository 类中添加(实体),如下所示。它由 uw.Table1.Add(_table1)

调用
public class UnitTestClass
{
    private readonly Table1 _table1 = new Table1()
    {
        TypeId = 4,
        Name = "TestAutomation",
        Description = "Test Automation",
        CreatedDate = DateTime.Now
    };

    [Fact]
    public void Add_Works()
    {
        int rowsAffected = 0;

        using (var uw = new UnitOfWork(new PortalDbContext()))
        {
            uw.Table1.Add(_table1);
            rowsAffected = uw.Commit();
        }

        Assert.Equal(1, rowsAffected);
    }

    [Fact]
    public void Add_WantToWork()
    {
        int rowsAffected = 0;

        var mockContext = new Mock<TestDbContext>();

        using (var uw = new UnitOfWork(mockContext.Object))
        {
            uw.Table1.Add(_table1);
            rowsAffected = uw.Commit();
        }

        Assert.Equal(1, rowsAffected);
    }
}

public abstract class ARepository<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey> 
    where TEntity : class, IEntity<TPrimaryKey>
{
    protected readonly DbContext Context;

    protected ARepository(DbContext context)
    {
        Context = context;
    }

    public void Add(TEntity entity)
    {
        Context.Set<TEntity>().Add(entity);
    }

}

2 个答案:

答案 0 :(得分:3)

问题是你在嘲笑对象但没有对象的方法。 它会是这样的:

mockContext.Setup(p => p.Set<Table1>().Add(It.IsAny<Table1>())).Returns(_table1);

这样,mock将创建dbSet的一个实例并返回你想要的内容

答案 1 :(得分:0)

在过去,我只有嘲笑它发生的经验,而不是数据库记录了。这属于集成测试领域,这是我的专业知识。我过去曾使用this method来完成模拟。

[TestMethod] 
    public void CreateBlog_saves_a_blog_via_context() 
    { 
        var mockSet = new Mock<DbSet<Blog>>(); 

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

        var service = new BlogService(mockContext.Object); 
        service.AddBlog("ADO.NET Blog", "http://blogs.msdn.com/adonet"); 

        mockSet.Verify(m => m.Add(It.IsAny<Blog>()), Times.Once()); 
        mockContext.Verify(m => m.SaveChanges(), Times.Once()); 
    } 

请注意以下几行。这些只是验证调用了add方法并调用了save更改。这足以解决你的挑战吗?

mockSet.Verify(m => m.Add(It.IsAny<Blog>()), Times.Once()); 
mockContext.Verify(m => m.SaveChanges(), Times.Once());