我正在编写一些单元测试,以下断言失败:
Assert.AreEqual(expected.Episode, actual.Episode);
如果我改为调用它,它会成功:
Assert.IsTrue(expected.Episode.Equals(actual.Episode));
我假设Assert.AreEqual()
最终调用Equals()
方法给出了它的类型,在本例中为Episode.Equals()
。
然而,在 Microsoft.VisualStudio.TestTools.UnitTesting.Assert 的封面下,我发现了以下代码(由ReSharper反编译):
public static void AreEqual<T>(T expected, T actual, string message, params object[] parameters)
{
if (object.Equals((object)expected, (object)actual))
return;
Assert.HandleFail...
}
这意味着AreEqual()
方法将expected
和actual
投射到object
以强制使用基本Equals()
方法,而不是我在Episode
课程中写的重载。基本方法只是检查引用是否相同,它们不是。
我有两个问题:
如果相关,这是我的方法:
public bool Equals(Episode other)
{
return Number == other.Number &&
CaseNote.Equals(other.CaseNote) &&
Patient.Equals(other.Patient);
}
答案 0 :(得分:6)
正在使用object.Equals(object,object)
,它处理的内容如下:
null
引用中的一个或两个?和然后继续使用{/ 1}} 之后它处理了这些事情。它必须将它们转换为x.Equals(y)
,因为这是object
所需的。转换为object.Equals(object,object)
也可以避免object
出现一些并发症(因为Nullable<T>
框可以是T?
,也可以是普通的null
。
但是,它也可以实现为:
T
处理 if (EqualityComparer<T>.Default.Equals(expected,actual))
return;
,Nullable<T>
,IEquatable<T>
vs struct
以及其他一些没有任何拳击的场景。
但是:当前的实现完成了这项工作,并且偶尔的盒子不是世界末日(并且:如果你的类型是class
,拳击甚至不是问题。)
答案 1 :(得分:4)
在您的代码中,您还需要覆盖Equals(object other)
(并且还需要覆盖GetHashCode)。
只需将其添加到您的代码中
即可public bool Equals(Episode other)
{
return Number == other.Number &&
CaseNote.Equals(other.CaseNote) &&
Patient.Equals(other.Patient);
}
public override bool Equals(object other)
{
Episode castOther = other as Episode;
if(castOther == null)
return false;
return this.Equals(castOther);
}
public override int GetHashCode()
{
//TODO: Implement using the members you used in "Equals(Episode other)"
throw new NotImplmentedExecption();
}
请记住,对于GetHashCode,如果两个对象相等,则必须也返回相同的哈希码。这是一个帮助可视化的快速图表。
您可能需要检查CaseNote
和Patient
是否存在类似问题。