NUnit AreEqual始终返回false

时间:2010-10-09 04:04:19

标签: unit-testing nhibernate nunit

我确定我在这里遗漏了一些简单但我无法弄清楚为什么我的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()通过。

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

谢谢!

3 个答案:

答案 0 :(得分:4)

您必须在班级上覆盖Equals()方法。否则NUnit将使用基本实现,它比较引用(这肯定不是你在此之后)

答案 1 :(得分:1)

根据建议您需要覆盖Equals。你需要注意副作用。

你也应该覆盖GetHashCode,否则你可能会得到.Equals为真的对象,但是使用你的Id类作为字典中的键,哈希不匹配会导致多个条目带有“Equal”ID。

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

想象一下如果.Equals是真的但是==是错误的混淆。

答案 2 :(得分:0)

需要像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对象是NHib代理也是如此。

Equals方法可能非常棘手,因为正确的方法很重要,因此理想情况下,您可以将其分解为某种Layer Supertype(Fowler)。许多开源项目,包括我之前提到的S#arp,提供了如何执行此操作的示例。

HTH,
Berryl