【问题标题】:Mock an Entity DbContext Insert模拟实体 DbContext 插入
【发布时间】:2018-08-15 18:48:01
【问题描述】:

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

}

【问题讨论】:

  • 如果您使用的是 EntityFramework,您应该能够找到一些允许您模拟 DBContext 的库。
  • 我可以模拟 DbContext。我的问题是当我尝试将对象添加到模拟的 DbContext 时。
  • 我是 EntityFrameworkMock 库的维护者,在 GitHubNuGet 上可用。它基于 Moq,因此您可以使用已知的设置和验证方法。

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


【解决方案1】:

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

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

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

【讨论】:

  • 这行得通。谢谢。 mockContext.Setup(p =&gt; p.Set&lt;Table1&gt;().Add(It.IsAny&lt;Table1&gt;())).Returns(_table1);
【解决方案2】:

在过去,我只嘲笑它发生了,而不是数据库记录了记录。这属于我的专业知识之外的集成测试领域。我过去曾使用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 changes。这足以解决您的挑战吗?

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

【讨论】:

  • System.NotSupportedException 未被用户代码处理。消息=非虚拟(在 VB 中可覆盖)成员上的设置无效:m => m.Table1s。我在mockContext.Setup(m =&gt; m.Table1s).Returns(mockSet.Object) 上收到此错误
猜你喜欢
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 2017-08-04
  • 2017-05-14
相关资源
最近更新 更多