How to implement unit tests on IEqualityComparer?

Viewed 1567

I have a class and a comparer for this class that implements IEqualityComparer:

class Foo
{
    public int Int { get; set; }
    public string Str { get; set; }

    public Foo(int i, string s)
    {
        Int = i;
        Str = s;
    }

    private sealed class FooEqualityComparer : IEqualityComparer<Foo>
    {
        public bool Equals(Foo x, Foo y)
        {
            if (ReferenceEquals(x, y)) return true;
            if (ReferenceEquals(x, null)) return false;
            if (ReferenceEquals(y, null)) return false;
            if (x.GetType() != y.GetType()) return false;
            return x.Int == y.Int && string.Equals(x.Str, y.Str);
        }

        public int GetHashCode(Foo obj)
        {
            unchecked
            {
                return (obj.Int * 397) ^ (obj.Str != null ? obj.Str.GetHashCode() : 0);
            }
        }
    }

    public static IEqualityComparer<Foo> Comparer { get; } = new FooEqualityComparer();
}

The two methods Equals and GetHashCode are used for example in List.Except via an instance of the comparer.

My question is: how to implement properly unit tests on this comparer? I want to detect if someone adds a public property in Foo without modifying the comparer, because in this case the comparer becomes invalid.

If I do something like:

Assert.That(new Foo(42, "answer"), Is.EqualTo(new Foo(42, "answer")));

This cannot detect that a new property was added, and that this property differs in the two objects.

Is there any way to do this?

If it is possible, can we add an attribute to a property to say that this property is not relevant in the comparison?

3 Answers
Related