模拟实体 DbContext 插入

Kev*_* C. 4 c# unit-testing moq xunit entity-framework-6

我正在使用XunitMoq。我希望能够模拟表中的插入。这样,记录实际上不会填充表,但单元测试可以验证插入是否成功。使用真实的 DbContext,单元测试适用于下面的方法Add_Works()。当我尝试在Add_WantToWork()中使用 Mock时,收到错误“对象引用未设置为对象的实例”。失败发生在ARepository类中的Context.Set().Add(entity)上,如下所示。它由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);
    }

}
Run Code Online (Sandbox Code Playgroud)

小智 5

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

mockContext.Setup(p => p.Set<Table1>().Add(It.IsAny<Table1>())).Returns(_table1);
Run Code Online (Sandbox Code Playgroud)

这样模拟将创建 dbSet 的实例并返回您想要的内容