是什么根据NUnit集合约束使类成为集合
本文关键字:集合 约束 NUnit 是什么 | 更新日期: 2023-09-27 18:27:32
我有一个实现ICollection<SomeConcreteClass>
的类。NUnit集合约束不将其识别为集合。
例如Assert.That( sut, Has.No.Member( someObjectOfTypeSomeConcreteClass ) );
抛出System.ArgumentException : The actual value must be a collection
而CCD_ 4在空CCD_。
那么,集合什么时候是集合(根据NUnit)?
堆栈跟踪:
System.ArgumentException : The actual value must be a collection Parametername: actual
at NUnit.Framework.Constraints.CollectionConstraint.Matches(Object actual)
at NUnit.Framework.Constraints.NotConstraint.Matches(Object actual)
MyTestFile.cs(36,0): at MyAssembly.MyTestFixture.MyTestMethod()
NUnit 2.4.3.0出现了上述问题。我刚用2.6试过。Is.Empty
现在工作,但Has.No.Member
仍然失败。它甚至不调用Equals()
或operator ==()
。它如何比较集合元素?RhinoMocks Arg<MyCollection>.List.Count( Is.Equal( 1 ) )
现在也失败了。
结论:
对于NUnit 2.4,集合约束要求实现非通用ICollection,以便将集合识别为集合(回答原始问题)。IEnumerable相等按预期工作。
在NUnit 2.6(可能是3.0)的情况下,即使Equals
被覆盖,匹配元素也会检查IEnumerable
s的相等性。这就是为什么如果元素本身是IEnumerable
,则成员关系约束不起作用。这是一个已知的问题(https://bugs.launchpad.net/nunit-3.0/+bug/646786)。
有关详细信息,请参阅我自己的答案。
查看NUnit 2.5.10的源代码后:约束首先将给定集合强制转换为非泛型IEnumerable
。
EDIT:然后它在集合上运行foreach()并比较项目。所以AFAICT应该会起作用。
您使用的NUnit版本是什么?
请参阅此处http://www.nunit.org/index.php?p=collectionConstraints&r=2.5,
对于引用,Has.Member使用对象相等来查找收集为了检查与集合中的项目相等的对象,使用Has.Some.EqualTo(…).
所以我认为您没有实现.Equals(SomeConcreteClass),或者集合应该是IEnumerable。
我想我想通了。
NUnit 2.4.3.0尝试强制转换为我没有实现的非泛型ICollection
。现在适用于2.4。
在NUnit 2.6.0.12051中,有一个NUnitEqualityComparer
可以执行以下操作:
if (x is IEnumerable && y is IEnumerable && !(x is string && y is string))
return EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance);
我的集合成员是IEnumerable的,在测试的情况下都是空的。这就是为什么约束认为所有实例都是相等的。但事实并非如此。NUnitEqualityComparer假定类具有成员(IEnumerable)或具有自己的状态。我的集合成员类(问题中称为SomeConcreteClass)既是可枚举的,也有其他状态,例如Name属性。由于NUnitEqualityComparer的工作方式,不会比较附加状态,并且具有不同附加状态的空对象被错误地认为是相等的。
我将与NUnit邮件列表讨论这一点,并在此处报告。
编辑:
这是已知的行为:https://bugs.launchpad.net/nunit-3.0/+bug/646786