Unit testing NUnit AreEqual总是返回false
我确信我遗漏了一些简单的东西,但我不明白为什么我的NUnit对象比较测试继续失败 我有一个简单的目标:Unit testing NUnit AreEqual总是返回false,unit-testing,nhibernate,nunit,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 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单元测试将保存的对象与检索到的对象进行比较,并对它们进行比较。我知道Areame()会失败,因为它们不是对对象的相同引用,但我希望AreEqual()会通过
如果我调试测试,我可以看到这两个对象在这些属性中似乎具有相同的值,我的测试仍然失败。有人能告诉我为什么吗
谢谢 您必须重写类上的
Equals()
方法。否则,NUnit将使用基本实现,它比较引用(这里肯定不是您要讨论的内容)您必须在类上重写Equals()
方法。否则NUnit将使用基本实现,它比较引用(这肯定不是您在这里要讨论的内容)您确实需要按照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“代理”的对象和另一个未被“代理”的对象之间进行相等性检查,它将由于类型不匹配而失败。解决方案(由提供)是将型式试验修改为如下:
public override bool Equals(object obj) {
...
if (GetType() != obj.GetTypeUnproxied())
{
return false;
}
...
}
protected virtual Type GetTypeUnproxied() { return GetType(); }
在所有情况下,即使compareTo对象是NHib代理,也可以有效地返回基础对象的类型
Equals方法可能很棘手,因为正确的方法很重要,因此理想情况下,您可以将其考虑到某种层超类型(Fowler)中。许多开源项目,包括我前面提到的S#arp项目,都提供了如何做到这一点的示例
HTH,Berryl您确实需要按照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“代理”的对象和另一个未被“代理”的对象之间进行相等性检查,它将因类型不匹配而失败。解决方案(由提供,将型式试验修改为如下内容:
public override bool Equals(object obj) {
...
if (GetType() != obj.GetTypeUnproxied())
{
return false;
}
...
}
protected virtual Type GetTypeUnproxied() { return GetType(); }
在所有情况下,即使compareTo对象是NHib代理,也可以有效地返回基础对象的类型
Equals方法可能很棘手,因为正确的方法很重要,因此理想情况下,您可以将其考虑到某种层超类型(Fowler)中。许多开源项目,包括我前面提到的S#arp项目,都提供了如何做到这一点的示例
HTH,Berryl正如建议的那样,您需要覆盖Equals。您确实需要了解其副作用 您还应该重写GetHashCode,否则您可能会得到.Equals为true的对象,但使用Id类作为字典中的键,哈希将不匹配,从而导致多个Id为“Equal”的条目 此外,您还需要重写==和!=运算符以保持一致的行为
想象一下,如果.Equals为真,而==为假,会出现混乱。正如建议的那样,您需要覆盖Equals。您确实需要注意其副作用 您还应该重写GetHashCode,否则您可能会得到.Equals为true的对象,但使用Id类作为字典中的键,哈希将不匹配,从而导致多个Id为“Equal”的条目 此外,您还需要重写==和!=运算符以保持一致的行为 想象一下,如果.Equals为真,但是==为假,那么会出现混乱。这也可能是重复的:这也可能是重复的: