【问题标题】:NUnit comparing two listsNUnit 比较两个列表
【发布时间】:2013-11-08 14:36:56
【问题描述】:

好的,所以我对单元测试还很陌生,到目前为止一切都很顺利。 我在这里简化了我的问题,但基本上我有以下几点:

[Test]
public void ListTest()
{
    var expected = new List<MyClass>();
    expected.Add(new MyOtherClass());
    var actual = new List<MyClass>();
    actual.Add(new MyOtherClass());
    Assert.AreEqual(expected,actual);
    //CollectionAssert.AreEqual(expected,actual);
}

但是测试失败了,测试不应该通过吗?我错过了什么?

【问题讨论】:

  • 在评论中使用 CollectionAssert,然后在 MyOtherClass 上实现 IComparable 接口。 NUnit 不知道如何比较这些对象,除非它们符合相等接口。
  • @vcsjones 我认为您的意思是 IEquatable 不是 IComparable 或覆盖 Equals 方法
  • @SriramSakthivel 你是对的 IEquatable 是正确的方法,如果你将它添加为答案,我会接受它。谢谢。
  • 是的,IEquatable 是正确的接口。
  • @SOfanatic 添加为答案 :)

标签: c# nunit generic-list


【解决方案1】:

如果您要比较两个列表,您应该使用collection constraints 进行测试。

Assert.That(actual, Is.EquivalentTo(expected));

此外,在您的类中,您将需要覆盖 Equals 方法,否则就像 gleng 所述,列表中的项目仍将根据参考进行比较。

简单的覆盖示例:

public class Example
{
    public int ID { get; set; }

    public override bool Equals(object obj)
    {
        return this.ID == (obj as Example).ID;
    }
}

【讨论】:

【解决方案2】:

让这个测试工作的一个非常简单的方法是只创建一次MyOtherClass 实例。这样,当比较两个列表中的项目时,它们将“相等”(因为它们引用相同的对象)。如果你这样做,CollectionAssert 就可以正常工作。

[Test]
public void ListTest()
{
    var thing = new MyOtherClass();

    var expected = new List<MyClass>();
    expected.Add(thing);

    var actual = new List<MyClass>();
    actual.Add(thing);

    CollectionAssert.AreEqual(expected,actual);
}

如果您不这样做,则需要在 MyOtherClass 中实现 IEquatable&lt;MyOtherClass&gt; 或覆盖 Equals 以定义使该类的两个实例“相同”的原因。

【讨论】:

    【解决方案3】:

    尝试更具体地说明您要实现的目标。明确告诉您要比较整个序列将解决问题。我个人不会依赖 NUnit 的花哨功能来确定您所说的 AreEqual 的意思。例如

    Assert.IsTrue(actual.SequenceEqual(expected));
    

    【讨论】:

    • 如果你想在你的 IDE 中获得更多信息,你应该依赖 NUnit 的花哨功能
    【解决方案4】:

    我将我的评论转换为应要求回答。

    好吧,这失败了,因为AreEqual 使用了参考比较。为了使它起作用,您需要进行值比较(您自己的自定义比较)。

    您几乎可以通过实现IEquatable 接口来做到这一点。请记住,在实现此接口时,您必须覆盖 Object.EqualsObject.GetHashCode 以获得一致的结果。

    .Net 框架支持在不实现 IEquatable 的情况下执行此操作,您需要 IEqualityComparer 应该可以解决问题,但 nunit 应该有一个将其作为重载的方法。不过,我不确定“nunit”。

    【讨论】:

      【解决方案5】:

      来自 Nunit documentation:

      从 2.2 版本开始,还为比较单维数组做出了特殊规定。如果两个数组的长度相同并且每个对应的元素都相等,则 Assert.AreEqual 会将两个数组视为相等。注意:目前不支持多维数组、嵌套数组(arrays of arrays)和ArrayList等其他集合类型。

      你有一个对象列表......所以它与比较 2 个整数不同。 您应该做的可能是比较列表中的所有对象...(尝试将您的列表转换为数组...可能确实有效:))


      正如我所说(以及大多数其他人),您可能需要覆盖 Equals。这是 MSDN 页面,介绍如何操作(涵盖 Equals、== 运算符和 GetHashCode)。

      类似的更多信息: [nunit 中两个对象之间的比较相等性]
      (Compare equality between two objects in NUnit)

      【讨论】:

      • 它不会,除非 Equals 被覆盖
      【解决方案6】:

      如果你不能修改一个类,那么这个例子会很有帮助:

      [Test]
      public void Arrays_Should_Be_Equal()
      {
          MyClass[] array1 = GetTestArrayOfSize(10);
          MyClass[] array2 = GetTestArrayOfSize(10);
      
          // DOESN'T PASS
          // Assert.That(array1, Is.EquivalentTo(array2));
      
          Func<MyClass, object> selector = i => new { i.Property1, i.Property2 };
          Assert.That(array1.Select(selector), Is.EquivalentTo(array2.Select(selector)));
      }
      
      private MyClass[] GetTestArrayOfSize(int count)
      {
          return Enumerable.Range(1, count)
              .Select(i => new MyClass { Property1 = "Property1" + i, Property2 = "Property2" + i }).ToArray();
      }
      

      【讨论】:

        猜你喜欢
        • 2011-06-19
        • 2011-02-15
        • 2021-04-15
        • 2013-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多