Comparing Two objects using Assert.AreEqual()

76,245

Solution 1

If you are using NUnit this is what the documentation says

Starting with version 2.2, special provision is also made for comparing single-dimensioned arrays. Two arrays will be treated as equal by Assert.AreEqual if they are the same length and each of the corresponding elements is equal. Note: Multi-dimensioned arrays, nested arrays (arrays of arrays) and other collection types such as ArrayList are not currently supported.

In general if you are comparing two objects and you want to have value based equality you must override the Equals method.

To achieve what you are looking for try something like this:

class Person 
{
    public string Firstname {get; set;}
    public string Lastname {get; set;} 

    public override bool Equals(object other) 
    {
      var toCompareWith = other as Person;
      if (toCompareWith == null) 
        return false;
      return this.Firstname ==  toCompareWith.Firstname && 
          this.Lastname ==  toCompareWith.Lastname; 
    }
}  

and in your unit test:

Assert.AreEqual(expectedList.ToArray(), actualList.ToArray());

Solution 2

These answers are far too complicated for the issue. There are no overrides necessary to compare two Lists, and you do not need to break out multiple asserts. Microsoft uses the following class, CollectionAssert.

CollectionAssert.AreEqual(expectedList, actualList)

This works for Lists, Dictionaries, and whatever else implements ICollection interface.

The microsoft documentation is at the following location and details the various types of assertions which can be made on collections

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.collectionassert.aspx

However, as mentioned by @Bart, this does not work as expected on Lists of (complex) Objects, and the Equals method may still need to be overwritten for those cases.

Solution 3

You could serialize them and test the resulting string.

Solution 4

Assert.AreEqual in xUnit on .NET will check if the objects are identical however object identity is different from value equallity it would seem you are looking for value equality. Ie. "Are the objects in my list of the same value?" which is why it "fails" the two lists are not identical even though the values of each object in each list might represent the same value.

Usually in a testing effort it should be enough to test the count of a collection and key elements.

var count = listA.Count;
Assert.AreEqual(count,listB.Count);
Assert.AreEqual(listA.First(),listB.first());
Assert.AreEqual(listA.Last(),listB.Last());
Assert.AreEqual(listA[count/2],listB[count/2]);

The last test doesn't have to be at the middle element and is simply meant to test an element in the list the only reason why it's not a random element is because you would want to be able to reproduce your test results.

Solution 5

Assert.AreEqual() compares references. Usually when comparing lists I compare the count of the items and than some properties of one exact item in the list or directly the item in the list (but again it is the reference).

If you want to compare objects by content than you would have to implement some recursive Object Comparer, but I don't think it is appropriate for Unit Tests, because you want them to run always as fast as possible.

Share:
76,245
Vishweshwar Kapse
Author by

Vishweshwar Kapse

Software developer at a startup company in Bangalore, India. Enjoy learning new technologies and languages. So far have been creating web applications using C#, asp.NET and SQL at the back end and a little bit of CSS,HTML in the front end.

Updated on May 16, 2020

Comments

  • Vishweshwar Kapse
    Vishweshwar Kapse almost 4 years

    I 'm writing test cases for the first time in visual studio c# i have a method that returns a list of objects and i want to compare it with another list of objects by using the Assert.AreEqual() method.

    I tried doing this but the assertion fails even if the two objects are identical.

    I wanted to know if this method, the two parameters are comparing references or the content of the object,

    Do I have to overload the == operator to make this work?