Reputation: 270790
In newer versions of NUnit, it is apparently possible to compare nested collections, as this answer said. However, it seems like this does not work so well with nested HashSet
s. Consider:
var a1 = new Dictionary<string, HashSet<string>> {
{ "a", new() { "b", "c" } },
{ "b", new() { "c" } },
{ "c", new() { } },
};
var a2 = new Dictionary<string, HashSet<string>> {
{ "c", new() { } },
{ "a", new() { "b", "c" } },
{ "b", new() { "c" } },
};
CollectionAssert.AreEqual(a1, a2);
This passes, but if I change the order in which I add values to the sets a little bit (or do anything that changes the iteration order of one of the sets):
var a1 = new Dictionary<string, HashSet<string>> {
{ "a", new() { "b", "c" } },
{ "b", new() { "c" } },
{ "c", new() { } },
};
var a2 = new Dictionary<string, HashSet<string>> {
{ "c", new() { } },
{ "a", new() { "c", "b" } },
{ "b", new() { "c" } },
};
CollectionAssert.AreEqual(a1, a2);
I expected it to still pass because a HashSet
is unordered, but the test fails:
----> NUnit.Framework.AssertionException : Expected and actual are both <System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.HashSet`1[System.String]]> with 3 elements
Values differ at index [0]
String lengths are both 1. Strings differ at index 0.
Expected: "b"
But was: "c"
-----------^
It seems like NUnit is not aware that HashSet
is unordered, but is aware that a Dictionary
is unordered.
So I think I need to use HashSet<string>.CreateSetComparer()
somewhere. I know I can specify the equality comparer to use for a comparison with Using
:
Assert.That(a, Is.EqualTo(b).Using(someEqualityComparer));
But I am trying to provide it for the comparison of the nested sets. How would I do that?
To avoid being an XY problem: The dictionary in my real code actually represents the edges of a control flow graph. It's actually a Dictionary<BasicBlock, HashSet<BasicBlock>>
.
Upvotes: 1
Views: 353
Reputation: 13681
NUnit isn't exactly "aware" that dictionaries are unordered. However, it does have special code for testing Dictionary equality, as described on this page. You'll note that the page doesn't say anything about Hashsets, which get no special treatment.
As you suggested, the simplest way to deal with Hashsets in your example is to define your own comparer. I suggest defining one, which implements, IEqualityComparer<Hashset>
. This will automatically take care of the nesting problem, since NUnit will only use that comparer when it reaches the nested Hashsets.
If necessary, you can repeat Using
to create multiple comparers for different types. However, from what you have said, that doesn't seem to be necessary in this case.
Upvotes: 1