Unit Test Assert.AreEqual failed

17,234

Solution 1

If you want to compare two different instances of Supplier, and want them to be considered equal when certain properties have the same value, you have to override the Equals method on Supplier and compare those properties in the method.

You can read more about the Equals method here: http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx

Example implementation:

public override bool Equals(object obj)
{
    if (obj is Supplier)
    {
        Supplier other = (Supplier) obj;
        return Equals(other.SupplierID, this.SupplierID) && Equals(other.SupplierName, this.SupplierName);
    }
    return false;
}

Note that you'll also get a compiler warning that you have to implement GetHashCode as well, that could be as simple as this:

public override int GetHashCode()
{
    return SupplierID;
}

Solution 2

As every other answer says the issue is that you're trying to compare instances of Supplier [probably] without overriding Equals method. But I do not think you should override Equals for test purposes since it may affect production code or you may need another Equals logic in production code.

Instead you should either assert each member one by one as you do it in first sample (if you do not have a lot of places where you want to compare entire object) or encapsulate this comparison logic in some class and use this class:

static class SupplierAllFieldsComparer
{
    public static void AssertAreEqual(Supplier expected, Supplier actual)
    {
        Assert.AreEqual(expected.SupplierID , actual.SupplierID );
        Assert.AreEqual(expected.SupplierName , actual.SupplierName );            
    }
}

// Test code:

SupplierAllFieldsComparer.AssertAreEqual(expected, actual);

Solution 3

The default implementation of Object.Equals for reference types (ie. classes) is "Reference Equality": are the two objects actually the same instance. It doesn't compare the values of fields.

Either (as others have shown) override Equals to give "Value Equality". In this caseyou must also override GetHashCode (so containers work), and should override operator ==.

Alternatively accept that most entities should have reference equality (two suppliers with the same name are not always the same organisation) and actually use the properties directly.

Solution 4

You compare 2 different instances of the Supplier type, that's why Assert fail.

If you want to Supplier are equals say (by their Id) you can override Equals method, here very over simpled example, :D.

public class Supplier
{
    private int id;
    private string name;

    public int Id
    {
        get { return id; }
    }

    public string Name
    {
        get { return name; }
    }

    public bool Equals(Supplier other)
    {
        if(other == null) return false;
        return other.id == id;
    }

    public override bool Equals(object obj)
    {
        if(obj == null) return false;
        if (obj.GetType() != typeof (Supplier)) return false;
        return Equals((Supplier) obj);
    }

    public override int GetHashCode()
    {
        return id;
    } 
}

Solution 5

When testing the individual properties, you compare the string/integer values. They are equal, and so the tests pass.

When testing the parent objects, you compare only the two container structures of type Supplier - and even though those may hold equal property values, they are not equal: Since you are instantiating two separate objects, they do not reside at the same address in memory.

Share:
17,234
Adrian S
Author by

Adrian S

Updated on June 04, 2022

Comments

  • Adrian S
    Adrian S almost 2 years

    I have a unit test for a method which gets an object from a collection. This keeps failing and I cannot see why, so I have created a very simple test below to create 2 supplier object and test they are equal to see if I can spot the problem in my test of my code. But this test again is failing. Can anyone see or explain why?

        [TestMethod()]
        public void GetSupplierTest2()
        {
            Supplier expected = new Supplier();
            expected.SupplierID = 32532;
            expected.SupplierName = "Test 1"
    
            Supplier actual = new Supplier();
            actual.SupplierID = 32532;
            actual.SupplierName = "Test 1"
    
            Assert.AreEqual(expected, actual);
        }
    

    But if I test the individual properties of the objects the test passes...

        [TestMethod()]
        public void GetSupplierTest2()
        {
            Supplier expected = new Supplier();
            expected.SupplierID = 32532;
            expected.SupplierName = "Test 1"
    
        Supplier actual = new Supplier();
            actual.SupplierID = 32532;
            actual.SupplierName = "Test 1"
    
            Assert.AreEqual(expected.SupplierID , actual.SupplierID );
            Assert.AreEqual(expected.SupplierName , actual.SupplierName );
        }
    
  • Adrian S
    Adrian S almost 13 years
    Thanks, so how would you unit test a scenario like this? Is it the right approach to just compare the values of each property or is there a method to compare an object with an object?
  • Adrian S
    Adrian S almost 13 years
    Thanks, so how would you unit test a scenario like this? Is there a method to compare an object with an object?
  • nathan gonzalez
    nathan gonzalez almost 13 years
    you could override the Equals function
  • Adrian S
    Adrian S almost 13 years
    Can you expand on this a little please?
  • Adrian S
    Adrian S almost 13 years
    Can you expand on overiding the Equals method please?
  • weltraumpirat
    weltraumpirat almost 13 years
    As the other two posters have suggested, you can override the Equals method of the Supplier type and have it compare the individual property values. See this tutorial, for example: msdn.microsoft.com/en-us/library/336aedhh(v=vs.71).aspx
  • steenhulthin
    steenhulthin almost 13 years
    I fully agree. I suggest reading this: stackoverflow.com/questions/1180044/…