【问题标题】:NUnit AreEqual always returns falseNUnit AreEqual 总是返回 false
【发布时间】:2011-04-23 04:17:49
【问题描述】:

我确定我在这里遗漏了一些简单的东西,但我无法弄清楚为什么我的 NUnit 对象比较测试继续失败。

我有一个简单的对象:

 public virtual int Id { get; private set; }

    public virtual string Description { get; set; }

    public virtual string Address { get; set; }

    public virtual string Ports { get; set; }

    public virtual string Password { get; set; }        

    public virtual ServerGroup ServerGroup { get; set; }

我将这个对象的一个​​实例保存到我的数据库中,然后使用 NHibernate 将其取出。我的 NUnit 单元测试将保存的对象与检索到的对象进行比较并进行比较。我知道 AreSame() 会失败,因为它们对对象的引用不同,但我希望 AreEqual() 通过。

如果我调试测试,我可以看到两个对象在这些属性中似乎具有相同的值,我的测试仍然失败。谁能告诉我为什么?

谢谢!

【问题讨论】:

标签: unit-testing nhibernate nunit


【解决方案1】:

你必须在你的类上覆盖Equals() 方法。否则,NUnit 将使用基础实现,它比较引用(这肯定不是你在这里所追求的)

【讨论】:

    【解决方案2】:

    您确实需要按照 Grzenio 的建议覆盖 Equals,但要注意 NHibernate 可能出现的细微混淆。具体来说,当启用延迟加载时,类型比较测试可能会失败。为了说明,这里有一段写得很好的 Equals 方法:

        // override object.Equals
        public override bool Equals(object obj)
        {
            //       
            // See the full list of guidelines at
            //   http://go.microsoft.com/fwlink/?LinkID=85237  
            // and also the guidance for operator== at
            //   http://go.microsoft.com/fwlink/?LinkId=85238
            //
    
            if (GetType() != obj.GetType())
            {
                return false;
            }
            ....
        }
    

    但是当启用延迟加载时,NHib 的工作方式是生成实际对象的代理(从而推迟不必要的数据库命中)。如果在一个已被 NHib“代理”的对象和另一个未被“代理”的对象之间进行相等性检查,则会因为类型不匹配而失败。解决方案(由S#arp Architecture project 提供,将类型测试修改为如下所示:

    public override bool Equals(object obj) {
        ...
        if (GetType() != obj.GetTypeUnproxied())
        {
            return false;
        }
           ...
     }
    
    protected virtual Type GetTypeUnproxied() { return GetType(); }
    

    这在所有情况下都有效地返回底层对象的类型,即使 compareTo 对象是 NIB 代理。

    Equals 方法可能很棘手,因为正确处理很重要,因此理想情况下,您可以将其分解为某种层超类型 (Fowler)。许多开源项目,包括我之前提到的 S#arp 项目,都提供了如何做到这一点的示例。

    HTH,
    贝瑞尔

    【讨论】:

      【解决方案3】:

      按照建议,您需要覆盖 Equals。您确实需要注意副作用。

      您还应该覆盖 GetHashCode,否则您最终可能会得到 .Equals 为 true 的对象,但使用您的 Id 类作为 Dictionary 中的键,哈希将不匹配,从而导致多个条目具有“Equal”ID。

      此外,您需要覆盖 == 和 != 运算符以保持一致的行为。

      想象一下,如果 .Equals 为真但 == 为假,会出现什么混乱。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-20
        • 2021-11-05
        • 2018-11-05
        • 2019-05-06
        • 2017-04-29
        • 2013-04-30
        • 2015-01-20
        相关资源
        最近更新 更多