在 C# 单元测试中比较两个 List<string[]> 对象

Tot*_*Zam 2 c# arrays unit-testing equality list

我正在尝试创建一个比较两个字符串数组列表的单元测试。

我尝试创建两个完全相同的List<string[]>对象,但是当我使用 时CollectionAssert.AreEqual(expected, actual);,测试失败:

[TestMethod]
public void TestList()
{
    List<string[]> expected = new List<string[]> {
        new string[] { "John", "Smith", "200" },
        new string[] { "John", "Doe", "-100" }
    };

    List<string[]> actual = new List<string[]> {
        new string[] { "John", "Smith", "200" },
        new string[] { "John", "Doe", "-100" }
    };

    CollectionAssert.AreEqual(expected, actual);
}
Run Code Online (Sandbox Code Playgroud)

我也尝试过Assert.IsTrue(expected.SequenceEqual(actual));,但也失败了。

如果我比较两个字符串列表或两个字符串数组,这两种方法都有效,但在比较两个字符串数组列表时它们不起作用。

我假设这些方法失败,因为它们正在比较两个对象引用列表而不是数组字符串值。

如何比较两个List<string[]>对象并判断它们是否真的相同?

Kap*_*pol 5

CollectionAssert.AreEqual(expected, actual);失败,因为它比较对象引用。expectedactual引用不同的对象。

Assert.IsTrue(expected.SequenceEqual(actual));由于同样的原因失败。这次比较expected和的内容actual,但元素本身是不同的数组引用。

也许尝试使用SelectMany展平两个序列:

var expectedSequence = expected.SelectMany(x => x).ToList();
var actualSequence = actual.SelectMany(x => x).ToList();
CollectionAssert.AreEqual(expectedSequence, actualSequence);
Run Code Online (Sandbox Code Playgroud)

正如Enigmativity在他的评论中正确注意到的那样,当数组和/或其元素的数量不同时,SelectMany 可能会给出积极的结果,但展平列表将导致元素数量相同。仅当您始终具有相同数量的数组和这些数组中的元素时,它才是安全的。


Jas*_*oyd 5

它失败是因为列表中的项目是对象 ( string[]) 并且由于您没有指定应如何CollectionAssert.AreEqual比较两个序列中的元素,因此它会回退到比较引用的默认行为。例如,如果您要将列表更改为以下内容,您会发现测试通过,因为现在两个列表都引用相同的数组:

var first = new string[] { "John", "Smith", "200" };
var second = new string[] { "John", "Smith", "200" };

List<string[]> expected = new List<string[]> { first, second};
List<string[]> actual = new List<string[]> { first, second};
Run Code Online (Sandbox Code Playgroud)

为了避免引用比较,您需要告诉CollectionAssert.AreEqual如何比较元素,您可以通过在IComparer调用它时传入 an 来做到这一点:

CollectionAssert.AreEqual(expected, actual, StructuralComparisons.StructuralComparer);
Run Code Online (Sandbox Code Playgroud)