Search code examples
c#.netmstest

Checking "value equality" of mutable classes in unit tests


In a project, I have several classes that are mutable.

In unit tests using MSTest, I'd like to check whether objects of those classes are what I expect, which basically means comparing some fields and properties of the objects, i.e. value equality.

As I understand, if I want to use Assert.AreEqual and CollectionAssert.AreEqual etc., I'd have to override Equals (and maybe implement IEquatable) and do the comparison of the fields and properties there.

But then, as I understand, to make sure nothing bad happens when somebody else uses these classes, maybe in a hash set, I have to override GetHashCode. But (according to several questions and answers on Stackoverflow) overriding Equals so that it provides value equality, and overriding GetHashCode for mutable classes cannot be done correctly.

Thus, in unit tests, how can I check that objects of mutable classes are kind of "value equal"?


Solution

  • The problem with overriding GetHashCode is that if you use the object in a hashSet or dictionary, and mutate the object, the dictionary/hashset will not work correctly.

    A workaround for this is to instead implement a IEqualityComparer<T>. That reduces the risk of bugs, since anyone using a dictionary would have to do extra work to specifically use your MyValueEqualityComparer.

    This EqualityComparer should be possible to use in the Assert.Equals Method, at least in the latest version of MSTest

    Assert.Equals( a, b, new MyValueEqualityComparer());