简体   繁体   中英

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

I have a problem using Fluent Assertions to compare two collections of type List<List<string>> . When using the Should().Equal() method (order is important) I get the following (cryptic ;-) message:

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

So, the objects appear to be equal. Also when debugging the objects appear to be exactly the same. When comparing two List<string> objects the test passes, no problems, but the same test with List<List<string>> fails. Am I using the wrong assertion method? Or does Fluent Assertions not handle this type of collection correctly?

While comparing a string using == checks value equality, List<string> checks the address of the list. This means two lists, containing the same elements are not the same because you are comparing the addresses of the lists instead of the items inside. Lets make an example:

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

To solve your problem you could combine SelectMany and SequenceEqual to compare the items inside the lists. Here is a small example:

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

Instead of Should().Equal() use actualList.ShouldBeEquivalentTo(expectedList. config => config.WithStrictOrder());

ShouldBeEquivalentTo method will check that both lists contains items with same values. In cases when list contains instance of reference types, it will compare the full object graph of those instances. Adding as a second parameter
config => config.WithStrictOrdering() will check that order of items is same as in expected list.

Should().Equal() on other hand will use "standard" equality check, where var listOne = new List<string> { "test" }; and var listTwo = new List<string> { "test" }; will be different instances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM