Pergunta

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", FirstName = "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?

Foi útil?

Solução 3

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;
        }

Outras dicas

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.

In MbUnit 3 you can use StructuralEqualityComparer:

Assert.AreElementsEqual(obj1,obj2, new StructuralEqualityComparer());

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top