Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 模拟实体DbContext插入_C#_Unit Testing_Entity Framework 6_Moq_Xunit - Fatal编程技术网

C# 模拟实体DbContext插入

C# 模拟实体DbContext插入,c#,unit-testing,entity-framework-6,moq,xunit,C#,Unit Testing,Entity Framework 6,Moq,Xunit,我正在使用Xunit和Moq。我希望能够模拟表中的插入。这样,记录实际上不会填充表,但单元测试可以验证插入是否成功。使用真实的DbContext,单元测试适用于下面的方法Add_works()。当我尝试模拟时,在Add\u WantToWork()中,我得到错误,“对象引用未设置为对象的实例”。失败发生在Context.set().Add(entity)中的ARepository类中,如下所示。它由uw.Table1.Add(_Table1)调用 public class UnitTestCla

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

}
公共类UnitTestClass
{
私有只读表1_Table1=新表1()
{
TypeId=4,
Name=“测试自动化”,
Description=“测试自动化”,
CreatedDate=DateTime.Now
};
[事实]
公共空间添加工程()
{
int rowsAffected=0;
使用(var uw=new UnitOfWork(new PortalDbContext()))
{
uw.表1.添加(_.表1);
rowsAffected=uw.Commit();
}
Assert.Equal(1,行受影响);
}
[事实]
公共无效添加\ u WantToWork()
{
int rowsAffected=0;
var mockContext=new Mock();
使用(var uw=newunitofwork(mockContext.Object))
{
uw.表1.添加(_.表1);
rowsAffected=uw.Commit();
}
Assert.Equal(1,行受影响);
}
}
公共抽象类ARepository:IRepository
其中tenty:类,tenty
{
受保护的只读DbContext上下文;
受保护的存储库(DbContext上下文)
{
上下文=上下文;
}
公共无效添加(TEntity实体)
{
Context.Set().Add(实体);
}
}

问题在于,您模拟的是对象,而不是对象的方法。 应该是这样的:

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

通过这种方式,mock将创建dbSet的一个实例,并将返回您想要的任何内容。过去,我只经历过模拟它的发生,而不是数据库获取了记录。这属于集成测试领域,这是我所不擅长的。我过去用它来完成一个模拟

[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()); 
    } 
[TestMethod]
public void CreateBlog通过上下文()保存日志
{ 
var mockSet=new Mock();
var mockContext=new Mock();
Setup(m=>m.Blogs).Returns(mockSet.Object);
var service=newblogservice(mockContext.Object);
AddBlog(“ADO.NET博客”http://blogs.msdn.com/adonet"); 
验证(m=>m.Add(It.IsAny()),Times.Once());
验证(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()); 
mockSet.Verify(m=>m.Add(It.IsAny()),Times.Once());
验证(m=>m.SaveChanges(),Times.Once());

如果您使用的是EntityFramework,您应该能够找到一些库,这些库允许您模拟DBContext。我可以模拟DBContext。我的问题是当我尝试向模拟的DbContext添加对象时。我是EntityFrameworkMock库的维护者,该库在和上可用。它基于最小起订量,因此您可以使用已知的设置和验证方法。这很有效。谢谢<代码>mockContext.Setup(p=>p.Set().Add(It.IsAny())).Returns(_table1)System.NotSupportedException未由用户代码处理。Message=非虚拟(在VB中可重写)成员上的设置无效:m=>m.Table1s。我在
mockContext.Setup(m=>m.Table1s.Returns(mockSet.Object)