当前位置: 首页 > 编程语言 > C#

NUnit的Is.Equal是否不能可靠地用于派生自泛型的类?

时间:2023-04-11 12:11:18 C#

NUnit的Is.Equal对于从泛型派生的类不能可靠地工作吗?今天我遇到了以下NUnit问题。我有一个类,派生自泛型类。我开始使用NUnit的Is.EqualTo()函数进行一些序列化测试和相等性测试。当本应失败的测试通过时,我开始怀疑有什么问题。当我改用obj1.Equals(obj2)时,它应该会失败。为了调查我创建了以下测试:namespaceNUnit.Tests{usingFramework;公共类ThatNUnit{[测试]publicvoidIsNotEqualTo_ClientsNotEqual_Passes(){varclient1=newDerrivedClient();varclient2=newDerrivedClient();client1.Name="玩家1";client1.SomeGenericProperty=client1.Name;client2.Name="玩家2";client2.SomeGenericProperty=client2.Name;Assert.That(client1.Equals(client2),Is.False);Assert.That(client1,Is.Not.EqualTo(client2));}[测试]publicvoidIsNotEqualTo_ClientsAreEqual_AlsoPasses_SomethingWrongHere(){varclient1=newDerrivedClient();varclient2=newDerrivedClient();client1.Name="玩家1";client1.SomeGenericProperty=client1.Name;client2.Name=client1.Name;client2.SomeGenericProperty=client1.Name;Assert.That(client1.Equals(client2),Is.True);Assert.That(client1,Is.Not.EqualTo(client2));}}publicclassDerrivedClient:Client{}publicclassClient{publicstringName{get;放;}公共TSomeGenericProperty{得到;放;}publicoverrideboolEquals(objectobj){if(ReferenceEquals(null,obj)){returnfalse;}if(ReferenceEquals(this,obj)){返回真;}if(obj.GetType()!=typeof(Client)){returnfalse;}returnEquals((Client)obj);}publicboolEquals(Clientother){if(ReferenceEquals(null,other)){returnfalse;}if(ReferenceEquals(this,other)){返回真;}returnEquals(other.Name,Name)&&Equals(other.SomeGenericProperty,SomeGenericProperty);}publicoverrideintGetHashCode(){unchecked{return((Name!=null?Name.GetHashCode():0)*397)^SomeGenericProperty.GetHashCode();}}publicoverridestringToString(){returnstring.Format("{0},{1}",Name,SomeGenericProperty);}}}第二个测试中的两个(实际上是相互冲突的断言):Assert.That(client1.Equals(client2),Is.True);Assert.That(client1,Is.Not.EqualTo(client2));这个测试应该以某种方式失败,但它没有!所以我深入研究了NUnit的源代码,结果发现在一些特殊的条件if()之后,ObjectsAreEqual(objectx,objecty)方法(最终通过Assertcall.That(x,Is).EqualTo(y))来到这行代码:returnx.Equals(y);我发现它非常令人困惑,因为我现在必须认为Is.EqualTo()只是需要更长的路线,但基本上应该与x.Equals(y)相同这是那些的完整方法(在NUNit.Framework.Constraints命名空间内)感兴趣的:publicboolObjectsEqual(objectx,objecty){this.failurePoints=newArrayList();如果(x==null&&y==null)返回真;如果(x==null||y==null)返回false;输入xType=x.GetType();输入yType=y。获取类型();如果(xType.IsArray&&yType.IsArray&&!compareAsCollection)returnArraysEqual((Array)x,(Array)y);如果(x是ICollection&&y是ICollection)返回CollectionsEqual((ICollection)x,(ICollection)y);if(xisIEnumerable&&yisIEnumerable&&!(xisstring&&yisstring))returnEnumerablesEqual((IEnumerable)x,(IEnumerable)y);如果(externalComparer!=null)返回externalComparer。对象相等(x,y);如果(x是字符串&&y是字符串)returnStringsEqual((string)x,(string)y);如果(x是流&&y是Stream)returnStreamsEqual((Stream)x,(Stream)y);if(xisDirectoryInfo&&yisDirectoryInfo)returnDirectoriesEqual((DirectoryInfo)x,(DirectoryInfo)y);如果(Numerics.IsNumericType(x)&&Numerics.IsNumericType(y))returnNumerics.AreEqual(x,y,reftolerance);if(tolerance!=null&&tolerance.ValueisTimeSpan){TimeSpanamount=(TimeSpan)tolerance.Value;if(xisDateTime&&yisDateTime)return((DateTime)x-(DateTime)y).Duration()<=amount;if(xisTimeSpan&&yisTimeSpan)return((TimeSpan)x-(TimeSpan)y).Duration()<=数量;}返回x.Equals(y);那么这里发生了什么以及如何解决它?我希望能够信任我的测试,所以必须再次使用NUnit我也不想开始使用Equals()而不是Is.EqualTo()(前者在测试失败时不会给我这么好的输出).提前致谢。更新:与此同时,我进一步研究了这个问题,发现了一个类似的问题,并发布了一个可能的解决方法。问题是第二个测试的第二个断言调用接受对象而不是客户端的Equals重载,因此此比较返回false://obj.GetType()返回Client.DerivedClientif(obj.GetType()!=typeof(Client)){返回false;}解决这个问题,可以将比较操作改为:如果分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注——if(obj.GetType()!=this.GetType())本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: