C# 单元测试中使用Moq的问题

C# 单元测试中使用Moq的问题,c#,.net,unit-testing,nunit,moq,C#,.net,Unit Testing,Nunit,Moq,我一直在探索模拟对象在单元测试中的使用,并一直在尝试.NET的Moq框架。我在尝试测试从数据库返回域对象的服务层方法时遇到了一些问题 以下是我的设置: [SetUp] public void DoSetupTasks() { mockDao = new Mock<IHibernateDao>(); _hibernateService = new HibernateService(mockDao.Object);

我一直在探索模拟对象在单元测试中的使用,并一直在尝试.NET的Moq框架。我在尝试测试从数据库返回域对象的服务层方法时遇到了一些问题

以下是我的设置:

    [SetUp]
    public void DoSetupTasks()
    {
        mockDao = new Mock<IHibernateDao>();
        _hibernateService = new HibernateService(mockDao.Object);
        mockDomainObject = new Mock<DomainBase>();
        dmBase = new DomainBase()
        {
            Id = 5
        };
    }
当我运行单元测试时,它抛出以下异常:

异常:非虚拟(在VB中可重写)成员上的设置无效:dmb=>dmb.Id.Equals(It.IsAny())


我承认,我对这个框架很不熟悉。我一直在尝试学习一些教程,但我还没有弄明白。请尝试以下内容:

[Test]
public void TestFindById() {

    const int TEST_ID = 5;
    // Configure your mock DAO to return a real DomainBase 
    // when FindById is called.
    mockDao
        .Setup(dao => dao.FindById(TEST_ID, It.IsAny<Type>())
        .Returns(new DomainBase() { Id = TEST_ID });

    var domainObject = _hibernateService.FindById(TEST_ID , typeof(DomainBase));

    // Make sure the returned object is a DomainBase with id == TEST_ID 

    Assert.IsEqual(TEST_ID , domainObject.Id);
    Assert.IsInstanceOf<DomainBase>(domainObject);

    // and verify that your mock DAO was called with the same argument passed to 
    // your NHibernate service wrapper:
    mockDao.VerifyAll();
}
[测试]
公共void TestFindById(){
const int TEST_ID=5;
//配置您的模拟DAO以返回真实的域库
//当调用FindById时。
莫克道
.Setup(dao=>dao.FindById(TEST\u ID,It.IsAny())
.Returns(new DomainBase(){Id=TEST_Id});
var domainObject=_hibernateService.FindById(TEST_ID,typeof(DomainBase));
//确保返回的对象是id==TEST\u id的DomainBase
IsEqual(TEST_ID,domainObject.ID);
Assert.IsInstanceOf(域对象);
//并验证使用传递给的相同参数调用了模拟DAO
//您的NHibernate服务包装器:
mockDao.VerifyAll();
}
您不需要模拟域对象——通常最好模拟数据层和服务,然后在测试逻辑代码和模拟服务层之间传递真实的域对象(包含样本/测试数据)

编辑:要测试save和delete方法,您需要执行以下操作。请注意,在调用mock方法时,我们是如何使用Moq库的Callback()方法来运行一些代码的,并且在该回调中,我们断言传递给方法的对象是我们期望的对象:

[Test]
public void TestSaveDomainBase() {

    const int OBJECT_ID = 5;

    mockDao
      .Setup(dao => dao.Save(It.IsAny<DomainBase>()))
      .Callback((DomainBase d) => {
         // Make sure the object passed to Delete() was the correct one
         Assert.AreEqual(OBJECT_ID, d.ID);
      });

    var objectToSave = new DomainObject() { Id = OBJECT_ID };

    _hibernateService.Save(objectToDelete);

    mockDao.VerifyAll();
}


[Test]
public void TestDeleteDomainBase() {

    const int OBJECT_ID_TO_DELETE = 5;

    mockDao
      .Setup(dao => dao.Delete(It.IsAny<DomainBase>()))
      .Callback((DomainBase d) => {
         // Make sure the object passed to Delete() was the correct one
         Assert.AreEqual(OBJECT_ID_TO_DELETE, d.ID);
      });

    var objectToDelete = new DomainObject() { Id = OBJECT_ID_TO_DELETE };

    _hibernateService.Delete(objectToDelete);


    mockDao.VerifyAll();
}
[测试]
public void TestSaveDomainBase(){
const int OBJECT_ID=5;
莫克道
.Setup(dao=>dao.Save(It.IsAny()))
.Callback((DomainBase d)=>{
//确保传递给Delete()的对象是正确的
Assert.AreEqual(OBJECT_ID,d.ID);
});
var objectToSave=newdomainobject(){Id=OBJECT\u Id};
_hibernateService.Save(objectToDelete);
mockDao.VerifyAll();
}
[测试]
public void TestDeleteDomainBase(){
const int OBJECT_ID_TO_DELETE=5;
莫克道
.Setup(dao=>dao.Delete(It.IsAny()))
.Callback((DomainBase d)=>{
//确保传递给Delete()的对象是正确的
aresequal(OBJECT_ID_TO_DELETE,d.ID);
});
var objectToDelete=new DomainObject(){Id=OBJECT\u Id\u TO\u DELETE};
_hibernateService.Delete(objectToDelete);
mockDao.VerifyAll();
}

谢谢!我将在明天对此进行一次尝试并报告,但只要看一下您的代码,它现在就更有意义了。您的示例非常有效。再次感谢,Dylan。还有一个问题:您如何编写一个测试来验证域对象是否持久化到数据库或删除对象?请参阅编辑。它是有点像相同的原理,但相反-创建域对象,将其传递到服务方法,然后在模拟中(通过回调)验证服务层是否将正确的对象传递给DAO上的正确方法。
[Test]
public void TestSaveDomainBase() {

    const int OBJECT_ID = 5;

    mockDao
      .Setup(dao => dao.Save(It.IsAny<DomainBase>()))
      .Callback((DomainBase d) => {
         // Make sure the object passed to Delete() was the correct one
         Assert.AreEqual(OBJECT_ID, d.ID);
      });

    var objectToSave = new DomainObject() { Id = OBJECT_ID };

    _hibernateService.Save(objectToDelete);

    mockDao.VerifyAll();
}


[Test]
public void TestDeleteDomainBase() {

    const int OBJECT_ID_TO_DELETE = 5;

    mockDao
      .Setup(dao => dao.Delete(It.IsAny<DomainBase>()))
      .Callback((DomainBase d) => {
         // Make sure the object passed to Delete() was the correct one
         Assert.AreEqual(OBJECT_ID_TO_DELETE, d.ID);
      });

    var objectToDelete = new DomainObject() { Id = OBJECT_ID_TO_DELETE };

    _hibernateService.Delete(objectToDelete);


    mockDao.VerifyAll();
}