c# – Moq验证使用在Return中修改的对象,而不是实际传入的对象
背景
我有一个使用NHibernate将对象持久化到数据库的类.当您为没有设置ID的对象调用MergeEntity时,NHibernate会在返回时使用ID填充该对象.为了确保我总是使用NHibernate使用的相同对象,我从“Save”函数传回更新的对象. 问题 我试图使用Moq来模拟相同的行为,这通常非常直观且易于使用;但是,我在验证使用正确的参数调用Save()时遇到了一些麻烦.我想验证传入的对象的ID是否为零,然后由Save函数正确设置.不幸的是,当我修改Moq.Returns()函数中的ID时,Moq.Verify函数使用修改后的值而不是传入的ID值. 为了说明,这是一个非常基本的类(我重写了ToString()函数,所以我的测试输出将显示调用模拟的Save()时使用的ID: public class Class1 { private readonly IPersistence _persistence; /// <summary>Initializes a new instance of the <see cref="T:System.Object" /> class.</summary> public Class1(IPersistence persistence) { _persistence = persistence; } public int Id { get; set; } public void Save() { _persistence.Save(this); } public override string ToString() { return Id.ToString(); } } 这是界面(非常直接): public interface IPersistence { Class1 Save(Class1 one); } 以下是我认为应该通过的测试: [TestFixture] public class Class1Tests { [Test] public void Save_NewObjects_IdsUpdated() { var mock = new Mock<IPersistence>(); mock.Setup(x => x.Save(It.IsAny<Class1>())) .Returns((Class1 c) => { // If it is a new object,then update the ID if (c.Id == 0) c.Id = 1; return c; }); // Verify that the IDs are updated for new objects when saved var one = new Class1(mock.Object); Assert.AreEqual(0,one.Id); one.Save(); mock.Verify(x => x.Save(It.Is<Class1>(o => o.Id == 0))); } } 不幸的是,它没有说它从未使用符合该标准的参数调用.对模拟进行保存的唯一调用是使用ID为1的对象.我已经验证了对象在进入返回函数时的ID为0.如果我更新Returns()函数中的值,是否我无法区分传递给模拟的内容和更新的内容? 解决方法
您可以将其切换为验证使用正确的对象完成了保存.然后声称Id已按预期更改.
[Test] public void Save_NewObjects_IdsUpdated() { //Arrange var expectedOriginalId = 0; var expectedUpdatedId = 1; var mock = new Mock<IPersistence>(); mock.Setup(x => x.Save(It.Is<Class1>(o => o.Id == expectedOriginalId))) .Returns((Class1 c) => { // If it is a new object,then update the ID if (c.Id == 0) c.Id = expectedUpdatedId; return c; }).Verifiable(); var sut = new Class1(mock.Object); var actualOriginalId = sut.Id; //Act sut.Save(); //Assert //verify id was 0 before calling method under test Assert.AreEqual(expectedOriginalId,actualOriginalId); //verify Save called with correct argument //ie: an object that matched the predicate in setup mock.Verify(); // Verify that the IDs are updated for new objects when saved Assert.AreEqual(expectedUpdatedId,sut.Id); } 通过在设置上应用过滤器并使其可验证,然后确认该方法实际上是使用ID为零的对象调用的. 我已经测试了这个并且它通过了.要确认这是否按预期工作,您可以在执行操作之前从预期的起始ID更改sut的ID.验证将失败,因为它与谓词不匹配. 这应该满足你想要达到的目标. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |