c# – Moq验证使用在Return中修改的对象,而不是实际传入的对象

c# – Moq验证使用在Return中修改的对象,而不是实际传入的对象,第1张

概述背景 我有一个使用NHibernate将对象持久化到数据库的类.当您为没有设置ID的对象调用MergeEntity时,NHibernate会在返回时使用ID填充该对象.为了确保我总是使用NHibernate使用的相同对象,我从“Save”函数传回更新的对象. 问题 我试图使用Moq来模拟相同的行为,这通常非常直观且易于使用;但是,我在验证使用正确的参数调用Save()时遇到了一些麻烦.我想验证传入 背景

我有一个使用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.验证将失败,因为它与谓词不匹配.

这应该满足你想要达到的目标.

总结

以上是内存溢出为你收集整理的c# – Moq验证使用在Return中修改的对象,而不是实际传入的对象全部内容,希望文章能够帮你解决c# – Moq验证使用在Return中修改的对象,而不是实际传入的对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1232234.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存