Assert.AreEqual对从List<>派生的类失败覆盖Equals()

时间:2013-07-25 15:52:18

标签: c# .net nunit

我一直在遇到NUnit的麻烦。我有一个继承自List并重写Equals()的类(因此当它们以不同的顺序包含相同的元素时,可以认为两个实例相等)。使用Assert.AreEqual时,它会失败,但是使用Assert.True并手动调用Equals会起作用:

[Test]
public void Equals()
{
    var dieSet1 = new DieSet {new Die(1), new Die(2)};
    var dieSet2 = new DieSet {new Die(2), new Die(1)};

    Assert.True(dieSet1.Equals(dieSet2)); //ok
    Assert.AreEqual(dieSet1, dieSet2);    //fails with an exception
}

以下是例外情况:

  

NUnit.Framework.AssertionException未被用户代码处理    的HResult = -2146233088    消息=预期和实际都有2个元素    值[0]的值不同    预期:    但是:

     

源= nunit.framework    堆栈跟踪:         在NUnit.Framework.Assert.That(Object actual,IResolveConstraint expression,String message,Object [] args)         at NUnit.Framework.Assert.AreEqual(Object expected,Object actual)         在C:\ dev_code \ DiceLib \ DiceLibTest \ DieSetTest.cs中的DiceLibTest.DieSetTest.Equals():第47行    InnerException:

我在Equals()中设置了一个断点,并确保在调用Assert.AreEqual时没有调用它。

我的班级是这样的:

public class DieSet : List<Die>, IRollable
{
}

我已经阅读了一些相关的问题,例如: NUnit doesn't work well with Assert.AreEqual

但我仔细检查了一下,我的Equals()方法有正确的签名。

public override bool Equals(object obj)
{
}

我的猜测是NUnit内部在List&lt;&gt;上有一些特殊的行为。和/或一般的数组和/或集合,我的类属于这些类别之一。我的另一个猜测是,我做错了什么,我没有看到明显的......

2 个答案:

答案 0 :(得分:5)

是的 - 它是documented

  

从版本2.4开始,可以比较多维数组,嵌套数组(数组数组)和集合。如果Assert.AreEqual具有相同的维度并且每个相应的元素相等,则两个数组或集合将被视为相等。

所以你可能基本上想要Assert.True版本。

对于大多数用户,这种行为可能是可取的 - 它恰好与您的特定用途相冲突。

就个人而言,我不会从List<T>派生出一个set-semantics类型来开始 - 如果你实现了ISet<T>(并使用了组合),那么它可能正常工作。

答案 1 :(得分:3)

CollectionAssert.AreEqualCollectionAssert.AreEquivalent是稍微更透明的方式,分别测试两个集合是否包含相同顺序或任何顺序的相同元素。如果我知道我正在比较收藏品,我倾向于尝试使用它们。