Comparing two objects that are the same in MbUnit
From MBUnit I am trying to check if the values of two objects are the same using
Assert.AreSame(RawDataRow, result);
However I am getting the following fail:
Expected Value & Actual Value : {RawDataRow: CentreID = "CentreID1",
CentreLearnerRef = "CentreLearnerRef1",
ContactID = 1, DOB = 2010-05-05T00:00:00.0000000,
Email = "Email1", ErrorCodes = "ErrorCodes1",
ErrorDescription = "ErrorDescription1", F开发者_C百科irstName = "FirstName1"}
Remark : Both values look the same when formatted but they are distinct instances.
I don't want to have to go through each property. Can I do this from MbUnit?
Basically, Assert.AreEqual
uses Object.Equals()
to verify the equality between the actual and the expected instance, while Assert.AreSame
uses Object.ReferenceEquals
.
If your class does not implement any built-in equality mechanism; for example by overriding Object.Equals
, you will end up with the issue you describe because MbUnit does not know how to compare two instances of the type under test.
There are several solutions. One of them is Coppermill's solution: you may want to implement a structural equality comparer based on reflection. But MbUnit has already a built-in feature like that. It's called StructuralEqualityComparer<T>
and it's very easy to use. So why reinventing the wheel?
Assert.AreSame(RawDataRow, result, new StructuralEqualityComparer<MyDataRow>
{
{ x => x.CentreID },
{ x => x.CentreLearnerRef, (a, b) => a.Equals(b, StringComparison.OrdinalIgnoreCase) },
{ x => x.ContactID },
// You can customize completely the comparison process...
});
Anyway, I suggest you read that article: http://interfacingreality.blogspot.com/2009/09/equality-assertions-in-mbunit-v3.html
You may also want to read that article in the Gallio wiki.
Are you specifically looking for referential equality? AreSame
is testing that both references point to the same object. From the doco:
Assert.AreSame
- Verifies that an actual value is referentially identical to some expected value.
If you are simply looking to compare that two instances of an object are logically equal, then AreEqual
is what you need.
Assert.AreEqual
- Verifies that an actual value equals some expected value.
I've ended up building my own using Reflections
private bool PropertiesEqual<T>(T object1, T object2)
{
PropertyDescriptorCollection object2Properties = TypeDescriptor.GetProperties(object1);
foreach (PropertyDescriptor object1Property in TypeDescriptor.GetProperties(object2))
{
PropertyDescriptor object2Property = object2Properties.Find(object1Property.Name, true);
if (object2Property != null)
{
object object1Value = object1Property.GetValue(object1);
object object2Value = object2Property.GetValue(object2);
if ((object1Value == null && object2Value != null) || (object1Value != null && object2Value == null))
{
return false;
}
if (object1Value != null && object2Value != null)
{
if (!object1Value.Equals(object2Value))
{
return false;
}
}
}
}
return true;
}
In MbUnit 3 you can use StructuralEqualityComparer:
Assert.AreElementsEqual(obj1,obj2, new StructuralEqualityComparer());
精彩评论