Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Test Assert.AreEqual failed

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 );
    }
like image 457
Adrian S Avatar asked Jun 13 '11 08:06

Adrian S


People also ask

What is assert areequal()?

Tests whether the specified objects are equal and throws an exception if the two objects are not equal. Different numeric types are treated as unequal even if the logical values are equal.

How to use assert Equals in c#?

Assert. Equal(expected.Name, actual.Name); The first example fails due to the way comparison works for reference types. By default, the equality operation for those types will only assert whether the two objects being compared are the same, namely your variables are pointing to the same object within the memory heap.

How do you compare two objects in assert?

In order to change the way two objects are compared in an assert we only need change the behavior of one of them – the expect value (might change depending on the unit testing framework).

Is equal to NUnit?

NUnit is able to compare single-dimensioned arrays, multi-dimensioned arrays, nested arrays (arrays of arrays) and collections. Two arrays or collections are considered equal if they have the same dimensions and if each pair of corresponding elements is equal.


3 Answers

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);
like image 197
Snowbear Avatar answered Jan 19 '23 01:01

Snowbear


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;
}
like image 29
Bubblewrap Avatar answered Jan 19 '23 01:01

Bubblewrap


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.

like image 25
Richard Avatar answered Jan 18 '23 23:01

Richard