Moq框架指定ON DELETE NO ACTION或ON UPDATE NO ACTION

时间:2017-06-30 10:08:23

标签: entity-framework moq

我在设置Moq框架时遇到了更新实体的简单测试问题,我尝试使用Moq我的实体框架,除了涉及编辑数据的测试外,它适用于所有测试。 我收到的错误是指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。我尽可能多地调查它,所有的建议都包括

        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

或添加

.WillCascadeOnDelete(假);

在我的外键上,我已经为创建数据库做了第一步。我觉得Moq似乎只是忽略了这些。 有没有人有这方面的经验,如果有任何建议?

由于

修改

工作测试

    [Test]
    public void TestInsert()
    {
        //Assign
        testCustomer = new Customer() { CustomerID = 2, CustomerName = "Test Customer", Active = true };

        mockContext = new Mock<efContext>();
        mockContext.Setup(x => x.Set<Customer>())
            .Returns(new FakeCustomerDbSet
            {
                testCustomer
            });

        mockUnitOfWork = DataAccess.GetMockUnitOfWork(mockContext.Object);
        ManageCustomer sut = new ManageCustomer(ref mockUnitOfWork);
        Customer testCustomer = new Customer() { CustomerName = "Test Customer2", Active = true };

        //Act
        sut.Insert(testCustomer);
        Customer testCustomer2 = sut.GetBy(x => x.CustomerName == "Test Customer2").SingleOrDefault();

        //Assert
        Assert.AreEqual(testCustomer, testCustomer2);
    }

测试方法

    public virtual T Insert(T entity)
    {
        dynamic dyn = entity;
        dyn.Active = true;

        entity = Repo.Insert((T)dyn);
        Repo.Commit();

        return entity;
    }

测试失败

    public void TestDeleteByEntity()
    {
        //Assign
        TestIntializer();
        ManageCustomer sut = new ManageCustomer(ref mockUnitOfWork);

        //Act
        sut.Delete(testCustomer);

        //Assert
        Assert.IsNull(sut.GetBy(x => x.CustomerID == testCustomer.CustomerID).SingleOrDefault());
    }

测试方法

    public virtual bool Delete(T entity)
    {
        dynamic DynamicEntity = entity;
        DynamicEntity.Active = false;

        return Update(DynamicEntity);
    }

    public virtual void Update(T entityToUpdate)
    {
        var attached = _context.ChangeTracker.Entries<T>().Where(x => x == entityToUpdate).FirstOrDefault();

        if (attached != null)
        {
            attached.CurrentValues.SetValues(entityToUpdate);
        }
        else
        {
            // Set the entity's state to modified
            _context.Entry(entityToUpdate).State = EntityState.Modified;
        }   
    }

1 个答案:

答案 0 :(得分:0)

我没有Update方法的所有细节,所以我不得不做一些猜测,但这就是它的样子:

在我看来,Update方法正在对您的mockUnitOfWork字段进行一些方法调用,而且它似乎不属于Mock<T>

类型

您应该传递Mock对象而不是具体实现。

看起来具体的实现是让你得到你提到的错误。通过使用单元的模拟版本

尝试仅将sut作为测试中的具体实现。除sut之外的任何其他代码都会使您的测试更少单位 ary。

另一方面,UnitOfWork.Delete()的实施将在另一项专门测试中进行测试。

但是,有一点需要测试发出SQL命令的类。此时,您可能希望保持该类尽可能薄,并测试它,而不是使用单元测试,而是使用集成测试。

为什么呢?简单地说,如果您测试SQL命令可以获得所需的结果,那么您就不会对您的工作单元进行单元测试:您正在测试所述工作单元与SQL数据库之间的集成。