是什么根据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被覆盖,匹配元素也会检查IEnumerables的相等性。这就是为什么如果元素本身是IEnumerable,则成员关系约束不起作用。这是一个已知的问题(https://bugs.launchpad.net/nunit-3.0/+bug/646786)。

有关详细信息,请参阅我自己的答案。

是什么根据NUnit集合约束使类成为集合

查看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