13 Answers
13

Override .Equals for your object and in the unit test you can then simply do this:

Assert.AreEqual(LeftObject, RightObject);

Of course, this might mean you just move all the individual comparisons to the .Equals method, but it would allow you to reuse that implementation for multiple tests, and probably makes sense to have if objects should be able to compare themselves with siblings anyway.

More Caveat: Implementing GetHashCode() on mutable types will misbehave if you ever use that object as a key. IMHO, overriding Equals(), GetHashCode() and making the object immutable just for testing does not make sense.
–
bavazaDec 9 '13 at 6:51

thanks. however, I had to switch the order of the actual and expected params since converntion is that expected is a param before actual.
–
Valamas - AUSSep 7 '11 at 5:49

this is a better approach IMHO, Equal & HashCode overrides shouldn't have to be based on comparing every field and plus that's very tedious to do across every object. Good job!
–
kibbled_bitsJul 13 '12 at 15:29

any idea why the code is not coloured by SO?
–
Louis RhysAug 29 '12 at 5:19

This works great if your type only has basic types as properties. However if your type has properties with custom types (that don't implement Equals) it will fail.
–
Bobby CannonAug 30 '13 at 20:24

This is an excellent way to test, especially if you're anyways dealing with JSON (e.g. using a typed client to access a web service). This answer should be much higher.
–
Roopesh ShenoyMar 22 '13 at 22:35

Your solution worked great for me thanks Max, I tried to add my own version in the comments but there wasn't enough space so have submitted it as a separate answer.
–
Sam AspinMay 29 '13 at 16:42

I prefer not to override Equals just to enable testing. Don't forget that if you do override Equals you really should override GetHashCode also or you may get unexpected results if you are using your objects in a dictionary for example.

I do like the reflection approach above as it caters for the addition of properties in the future.

For a quick and simple solution however its often easiest to either create a helper method that tests if the objects are equal, or implement IEqualityComparer on a class you keep private to your tests. When using IEqualityComparer solution you dont need to bother with the implementation of GetHashCode. For example:

I agree with ChrisYoxall -- implementing Equals in your main code purely for testing purposes is not good.

If you are implementing Equals because some application logic requires it, then that's fine, but keep pure testing-only code out of cluttering up stuff (also the semantics of checking the same for testing may be different than what your app requires).

In short, keep testing-only code out of your class.

Simple shallow comparison of properties using reflection should be enough for most classes, although you may need to recurse if your objects have complex properties. If following references, beware of circular references or similar.

Max Wikstrom's JSON solution (above) makes the most sense to me, it's short, clean and most importantly it works. Personally though I'd prefer to implement the JSON conversion as a separate method and place the assert back inside the unit test like this...

@Kos: I refactored it to use lambda expressions instead of strings, which is great. It lacks a couple of features that might be useful or even essential for general use. I wonder if it could ever be as powerful and easy to use at the same time as I wish it to be. However, it is still not OSS and I need to ask my boss and put some time into it. The former would be done quite quickly, the latter is kind of a problem ... Your question encourages me to put some effort into it.
–
Stefan SteineggerFeb 10 '12 at 6:55

2

If you've never been able to publish this after 3 years this answer really should be deleted since it's not helpful to anyone else.
–
Dan NeelyAug 21 '12 at 20:19

I would build on the answer of @Juanma. However, I believe this should not be implemented with unit test assertions. This is a utility that could very well be used in some circumstances by non-test code.

I've tried several approaches mentioned here. Most involve serializing your objects and doing a string compare. While super easy and generally very effective, I've found it comes up a little short when you have a failure and something like this gets reported:

Another option is to write a custom constraint by implementing the NUnit abstract Constraint class. With a helper class to provide a little syntactic sugar, the resulting test code is pleasantly terse and readable e.g.

Assert.That( LeftObject, PortfolioState.Matches( RightObject ) );

For an extreme example, consider class which has 'read-only' members, is not IEquatable, and you could not change the class under test even if you wanted to:

The contract for the Constraint class requires one to override Matches and WriteDescriptionTo (in the case of a mismatch, a narrative for the expected value) but also overriding WriteActualValueTo (narrative for actual value) makes sense:

https://github.com/kbilsted/StatePrinter has been written specifically to dump object graphs to string representation with the aim of writing easy unit tests. It even has its own extended Assert methods which output a properly escaped string representation in case of error for easy copy-paste into the test to correct it.