是什么使一个类成为根据NUnit集合约束的集合?

时间:2012-03-12 07:43:26

标签: c# .net collections nunit constraints

我有一个实现ICollection<SomeConcreteClass>的类。 NUnit集合约束不会将其识别为集合。

e.g。 Assert.That( sut, Has.No.Member( someObjectOfTypeSomeConcreteClass ) );抛出System.ArgumentException : The actual value must be a collection

Assert.That( sut, Is.Empty );失败,空sut

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

有关详情,请参阅我自己的答案。

3 个答案:

答案 0 :(得分:2)

在查看NUnit 2.5.10的源代码之后:约束首先将给定集合强制转换为非泛型IEnumerable

编辑:然后它在集合上运行foreach()并比较项目。所以AFAICT应该可行。

您使用的是什么版本的NUnit?

答案 1 :(得分:1)

请参阅此处http://www.nunit.org/index.php?p=collectionConstraints&r=2.5

  

对于引用,Has.Member使用对象相等来查找a中的成员   采集。要检查与集合中的项目相等的对象,   使用Has.Some.EqualTo(...)。

所以我认为你没有实现.Equals(SomeConcreteClass),或者集合应该是IEnumerable。

答案 2 :(得分:1)

我想我已经明白了。

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