Search code examples
c#serializationmbunit

MbUnit: Comparing distinct object instances


I'd like to know whether there is a way to compare two objects in MBUnit so that the test is passed when the objects "look" the same, even if those are distinct instances?

For example:

[TestFixture]
class ComparisonTestFixture
{

    class foo
       {
           public string bar;
       }

    [Test]
    public void ComparisonTest()
    {

        foo foo1 = new foo()
           {
               bar = "baz"
           };

        foo foo2 = new foo()
            {
                bar = "baz"
            };


        //This assertion should be successful, but it isn't
        //*** Failures ***
        //Expected values to be equal.
        //Expected Value & Actual Value : {foo: bar = "zzz...."}
        //Remark : Both values look the same when formatted but they are distinct instances.
        Assert.AreEqual(foo1,foo2);
    }
}

Assert.AreEqual() does not work for this (test fails, see source code above). Since it remarks that "Both values look the same when formatted but they are distinct instances", I figure there must be some way to do this built into MbUnit already without serializing the objects to XML in my own code.

Do I have to write my own Assert extension method for this?


Solution

  • I would suggest that you override the Equals method on your class to perform the comparison you want. This allows you to define value equality instead of reference equality. One caveat is that you also have to override GetHashCode if you override Equals to ensure that two object that are equal also returns the same hash code. Here is a very simple example;

    public class Foo {
    
      public String Bar {
        get;
        set;
      }
    
      public String Baz {
        get;
        set;
      }
    
      public override Boolean Equals(Object other) {
        Foo otherFoo = other as Foo;
        return otherFoo != null
          && Bar.Equals(otherFoo.Bar)
          && Baz.Equals(otherFoo.Baz);
      }
    
      public override Int32 GetHashCode() {
        return Bar.GetHashCode() ^ Baz.GetHasCode();
      }
    
    }
    

    If you don't want to override Equals and you really just want to compare instances property by property you could use reflection:

    public static Boolean AreEqual<T>(T a, T b) {
      foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
        if (!Object.Equals(propertyInfo.GetValue(a, null),
                           propertyInfo.GetValue(b, null)))
          return false;
      return true;
    }