模拟实体 DbContext 插入

Mock an Entity DbContext Insert

我正在使用 Xunit & Moq。我希望能够模拟插入 table。这样,记录实际上不会填充 table,但单元测试可以验证插入是否成功。使用真实的 DbContext,单元测试适用于下面的方法 Add_Works()。当我尝试使用 Mock 时,在 Add_WantToWork() 中,我得到错误,"Object reference not set to an instance of an object." 失败发生在 Context.Set().Add(entity)ARepository class 中,也如下所示。它由 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);
    }

}

问题是您在模拟对象,但没有模拟对象的方法。 它会是这样的:

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

这样 mock 将创建一个 dbSet 的实例,并且return你想要的任何东西

过去,我的经验只是嘲笑它发生了,而不是数据库记录了记录。这属于集成测试领域,这超出了我的专业知识。我过去曾使用 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()); 
    } 

注意以下几行。这些只是验证调用了添加方法并调用了保存更改。这足以解决您的挑战吗?

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