FluentAssertions - how to exclude comparison of dictionary keys?

Using Should().BeEquivalentTo() I want to compare 2 objects which contain a series of key-value pairs but to exclude the actual value of the keys because that will vary. So basically I'm only interested in comparing the contents of the Values. Example:

MyObject { MyDictionary1 { Key, Value } ... MyDictionary2 { Key, Value } }

compared to

ExpecterdObject { ExpectedDictionary1 { Key, Value } ... ExpectedDictionary2 { Key, Value } }

The 2 objects being of the same class with the same structure but with each instance having unique ids as keys.

I already tried

.Excluding(e => e.KayValuePair.Keys)

which doesn't seem to work as I still get errors saying that

Expected member MyDictionary1 to be a collection with 3 item(s). Expected member MyDictionary1 to contain key X.


Solution 1:

If you have an object structure like MyClass, and you want to override how the Dictionary property is compared between two instances of MyClass. Namely that only the Values of the dictionaries are compared.

class MyClass
{
    public int Value { get; set; }

    public Dictionary<int, string> Dictionary1 { get; set; }

    public Dictionary<int, string> Dictionary2 { get; set; }
}

To do that you can use a combination of Using and WhenTypeIs from the documentation.

Here's a complete example for your case, where the dictionaries have the same Values, but the Keys differ.

public void MyTestMethod()
{
    var expected = new MyClass
    {
        Value = 42,
        Dictionary1 = new Dictionary<int, string>
        {
            [1] = "foo",
            [2] = "bar"
        },
        Dictionary2 = new Dictionary<int, string>
        {
            [3] = "bar",
            [4] = "baz"
        }
    };

    var actual = new MyClass
    {
        Value = 42,
        Dictionary1 = new Dictionary<int, string>
        {
            [5] = "foo",
            [6] = "bar",
        },
        Dictionary2 = new Dictionary<int, string>
        {
            [7] = "bar",
            [8] = "baz",
        }
    };

    actual.Should().BeEquivalentTo(expected, options => options.
        Using<Dictionary<int, string>>(ctx => ctx.Subject.Values.Should().BeEquivalentTo(ctx.Expectation.Values))
        .WhenTypeIs<Dictionary<int, string>>());
}