I have a project in which I am receiving objects as DTOs and I am converting them to View-Models. In order to do this conversion I decided to make custom converters which does some calculation in order to convert from DTOs properties to View-Models. After all of these were ready, and the conversion was working, I wanted to add some unit tests to the conversion in order to make it more stable (I know this does not respect TDD, but this is what I managed to do).
The problem comes when I want tests to verify the equality of two View-Models
Assert.AreEqual(expected, actual);
Because none of the View-Models define Equals
method, and they will never be equal as reference. There are some approaches I thought about and found to compare these objects:
To define the Equals
method. But I don't know if it is a good practice to define it, only for testing purposes. And if I define it, it will be recommended to define the GetHashCode
method too, so I don't feel that this solution is the best.
Another possibility I thought is to implement IEqualityComparer<T>
in the test project, to isolate the comparison logic from the main conversion project, or even extracting this into a 3rd project, so the conversion module could use it in future if it's necessary. This implementation looks good, but I don't know if it's worth to add another project with many classes, which should be tested too.
The 3rd approach I found on a Stack Overflow question, which looks interesting, is to serialize both objects and compare the strings. The problem is that I don't know if this is a good practice of programming.
Which of these would be the best way to compare the objects? Am I missing some approaches that could be more efficient?
Note: The View-Models are complex objects, and I can not change the way of conversion to other technologies.
Your second approach is much better than the other two, because it keeps tests-specific code together with unit tests, and also because it lets you change your definition of what it means for two View-Models to be equal.
It's hardly worth it to move equality comparers into a separate project, though: if you intend to share equality comparison logic, then you might as well put it into your objects. If, on the other hand, it is designed only for testing, then you should keep it together with the tests (i.e. use your approach #1).
The approach based on serialization is too fragile, because it relies on an unrelated feature (i.e. serialization) to test the feature that you are actually testing (i.e. conversion).