Click here to Skip to main content
Licence CPOL
First Posted 5 Jan 2008
Views 11,240
Downloads 63
Bookmarked 7 times

Testing Equality of Two Objects

By Carl Johansen | 13 Jan 2008
A general purpose C# method for testing whether two objects have the same values in their respective public properties
1 vote, 14.3%
1

2
3 votes, 42.9%
3
1 vote, 14.3%
4
2 votes, 28.6%
5
2.81/5 - 7 votes
μ 2.81, σa 2.45 [?]

Introduction

A while ago, I was looking for a way to compare two objects as part of a unit test. I didn't want Assert.AreSame() because I didn't just want to see if they were the same object, and I didn't want Assert.AreEqual() because I didn't want to have to override Equals(). Ideally I wanted a general utility that would compare any two objects and say whether they were equal. I decided to define “equal” as “having the same value for all public properties”. I wanted a deep comparison, so if a public property is another object then all of its public properties should also be checked.

My search led me to the AssertGraphPropertiesEqual function written by Keith Brown. This was just the kind of thing I had in mind, but in using it I made a number of changes that I think made it generally more useful. I would like to share my version with you. These are the main changes in my version:

  1. I named it AssertPublicPropertiesEqual, but feel free to change that name if you don't like it.
  2. It is more consistent in its handling of an object that is passed as a parameter to the method and an object that is a property of that parameter. Making this change solved a number of problems that I was having with the original.
  3. It attempts to detect and short-circuit circular references.
  4. It allows you to supply an ‘ignore list’ of properties. For example, you might consider two List<string> objects that contain the same strings to be equal even though their Capacity property values are different.
  5. It ignores indexed properties (such as String.Chars). Normally these will be covered by the check of some other non-indexed property.
  6. The original contains this test: pi.PropertyType.IsAssignableFrom(typeof(IEnumerable)). That seemed to be the wrong way around, so I changed it to typeof(IEnumerable).IsAssignableFrom(objectType).

Using the Code

The method is intended to be used in unit testing, so it uses standard Asserts to perform the comparisons. I have tried it with both Visual Studio Team System (VSTS) and NUnit. Just include the appropriate using statement for the library that you use.

A typical call would be something like this:

MyClass expectedObject = the expected result of the test;
MyClass actualObject = MethodBeingTestedThatReturnsAMyClassObject(); 
UnitTestingHelper.AssertPublicPropertiesEqual(expectedObject, actualObject);

As I mentioned above, you can specify properties to be ignored during the comparison. Here's how to ignore the Capacity property of List<string> objects:

MyClass expectedObject = the expected result of the test;
MyClass actualObject = MethodBeingTestedThatReturnsAMyClassObject();

IgnoreProperties ignoreProps = new IgnoreProperties();
ignoreProps.Add(new PropertyComparisonExclusion(typeof(List<string>), "Capacity"));

UnitTestingHelper.AssertPublicPropertiesEqual
    (expectedObject, actualObject, ignoreProps);

When defining PropertyComparionExclusions, you can use the typeAction property to specify whether to ignore the property only on the specified type, or on the type and all its derived types. The default is PropertyComparisonExclusionTypeAction.MatchExactType, meaning that the property is ignored only on the specified type.

Conclusion

I have two questions:

  1. Is this useful for you?
  2. Have I got it right?

I've thrown various objects at it, but the possible inputs are literally infinite so please let me know if you find a problem with it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Carl Johansen

Software Developer

United Kingdom United Kingdom

Member
Carl Johansen is a .NET developer blah blah, lives in London blah blah, hobbies include juggling blah.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Question[My vote of 1] Didnt work for me - Stack overflow error. PinmemberMS_Jocker17:37 11 Mar '09  
AnswerRe: [My vote of 1] Didnt work for me - Stack overflow error. PinmemberMS_Jocker17:52 11 Mar '09  
and also for a simple class it didnt work for me, i just used your file in my solution, modifying the namespace required for unit test framework of VS2008. but still it didnt work , dont know what the problem.
 
please test for a class.
 
class temp
{
int a ;
string s;
public temp(int k,string t)
{
a = k;
s = t;
}
}
temp t = new temp(10,"sam");
temp s = new temp(20,"saml");
 
UnitTestingHelper.AssertPublicPropertiesEqual(t, s);
GeneralRe: [My vote of 1] Didnt work for me - Stack overflow error. PinmemberCarl Johansen1:43 12 Mar '09  
GeneralRe: [My vote of 1] Didnt work for me - Stack overflow error. PinmemberMS_Jocker19:04 12 Mar '09  
AnswerRe: [My vote of 1] Didnt work for me - Stack overflow error. PinmemberCarl Johansen14:24 23 Mar '09  
AnswerRe: [My vote of 1] Didnt work for me - Stack overflow error. PinmemberCarl Johansen3:34 12 Mar '09  
GeneralJust what I was looking for PinmemberDancingJester5:55 15 Aug '08  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120210.1 | Last Updated 13 Jan 2008
Article Copyright 2008 by Carl Johansen
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid