Several ways to Compare two C# objects while Unit Testing
So as per dictionary compare means
estimate, measure, or note the similarity or dissimilarity between.
Every software engineer would have come across comparing two objects/instances of same type. Today, will discuss how I was comparing two objects of same type in my initial days of my career then later figured out that there is better & easier solution. So, let’s see how it all started and can be done from beginner to pro. Those who are well verse in C# you can go directly to Solution 4 (Fluent Assertions).
Here is my class
here is the dumbest ever comparison I have ever seen even & I have done that too in my earlier days of my career.
and this unit tests will pass because all property values are the same between two objects. Here we are testing all the properties individually which is not an efficient way to do so why not try asserting both objects like
Assert.AreEqual(expected, actual);
but this test method fails with message
Assert.AreEqual failed. Expected:<Employee>. Actual:<Employee>.
even though all the properties values are the same it fails. The reason it failed it because in c# by default a class gets inherited from System.Object which has its own methods like Equals(), GetHashCode(), ToString() and few more.
Assert.AreEqual(expected, actual)
will make use of Equals() method and we have not overridden/implemented it in our Employee class.
Solution 1 [Equals( )]
Here we have implemented method Equals() and it requires GetHashCode() also to be overridden.
Now if we run the unit test it will pass.
Solution 2 [IEqualityComparer]
In the previous solution we implemented Equals() method hence we were able to compare two objects. What if it is a DTO (Data Transfer Object) or is third party/external library then we don’t have control over implementing Equals() method in it. We have a solution to it by making use of IEqualityComparer<T> Interface & below is the implementation
and now our unit test method will look like below
and our unit test pass.
Solution 3 [Serialize]
I have also seen smart people avoid writing all these comparisons implementation codes and instead rely on JsonSerializers & XmlSerializers like below
basically serialize to any string/text based format and then compare both strings.
Solution 4 [Fluent Assertion]
What if I tell you there is an even simpler way to compare two objects in unit tests without even writing any extra implementation code.
and then this test will pass, provided you must install NuGet package Fluent Assertions.
Let’s see a failed scenario and see what’s going to be error message
Expected property actual.Code to be “E01”, but “E02” differs near “2” (index 2).
the above message is extremely readable as far I have ever seen.
You can do more with Fluent Assertions by customizing and to know more about object comparison have a look at https://fluentassertions.com/objectgraphs/
Yes, there are many other NuGet packages like Shouldly and many others.
Please share your valuable comments and feedback.