List<List<string>> 的流利断言和比较

Fluent assertions and comparison of List<List<string>>

我在使用 Fluent Assertions 比较两个 List<List<string>> 类型的集合时遇到问题。使用 Should().Equal() 方法(顺序很重要)时,我收到以下(神秘 ;-) 消息:

Expected collection to be equal to {{"Telefoonnummer"}, {"E-mailadres"}, {"E-mailadres controle"}}, but {{"Telefoonnummer"}, {"E-mailadres"}, {"E-mailadres controle"}} differs at index 0.

因此,对象看起来是相等的。此外,在调试对象时,它们看起来完全相同。当比较两个 List<string> 对象时,测试通过,没有问题,但与 List<List<string>> 相同的测试失败。我使用了错误的断言方法吗?还是 Fluent Assertions 无法正确处理此类集合?

虽然使用 == 比较 string 检查值是否相等,但 List<string> 检查列表的地址。这意味着包含相同元素的两个列表并不相同,因为您比较的是列表的地址而不是其中的项目。让我们举个例子:

List<string> listA = new List<string> { "item" };
List<string> listB = new List<string> { "item" };
bool equal = listA == listB; //equal will be false

要解决您的问题,您可以结合使用 SelectManySequenceEqual 来比较列表中的项目。这是一个小例子:

List<List<string>> listToCompare = new List<List<string>>()
{
    new List<string> {"first", "second"},
    new List<string> {"third"}
};
List<string> expectedList = new List<string> { "first", "second", "third" };
bool sequenceEqual = listToCompare.SelectMany(i => i).SequenceEqual(expectedList); //sequenceEqual will be true

而不是 Should().Equal() 使用 actualList.ShouldBeEquivalentTo(expectedList. config => config.WithStrictOrder());

ShouldBeEquivalentTo 方法将检查两个列表是否包含具有相同值的项目。如果列表包含引用类型的实例,它将比较这些实例的完整对象图。添加为第二个参数
config => config.WithStrictOrdering() 将检查项目的顺序是否与预期列表中的顺序相同。

另一方面,

Should().Equal() 将使用 "standard" 相等性检查,其中 var listOne = new List<string> { "test" };var listTwo = new List<string> { "test" }; 将是不同的实例。