tags:

views:

165

answers:

2

I'm new to NUnit and looking for an explination as to why this test fails?

I get the following exception when running the test.

NUnit.Framework.AssertionException: Expected: equivalent to < <....ExampleClass>, <....ExampleClass> > But was: < <....ExampleClass>, <....ExampleClass> >

using NUnit.Framework;
using System.Collections.ObjectModel;

public class ExampleClass
{
    public ExampleClass()
    {
        Price = 0m;
    }

    public string Description { get; set; }
    public string SKU { get; set; }
    public decimal Price { get; set; }
    public int Qty { get; set; }
}

[TestFixture]
public class ExampleClassTests
{
    [Test]
    public void ExampleTest()
    {

        var collection1 = new Collection<ExampleClass>
               {
                     new ExampleClass
                         {Qty = 1, SKU = "971114FT031M"},
                     new ExampleClass
                         {Qty = 1, SKU = "971114FT249LV"}
                 };

        var collection2 = new Collection<ExampleClass>
               {
                     new ExampleClass
                         {Qty = 1, SKU = "971114FT031M"},
                     new ExampleClass
                         {Qty = 1, SKU = "971114FT249LV"}
                 };

        CollectionAssert.AreEquivalent(collection1, collection2);

    }
}
+3  A: 

You need to implement Equals and GetHashCode on your ExampleClass. Without that, NUnit is doing a reference equality check ("are these the exact same object?"), not a value equality one ("do these objects look alike?").

Tim Robinson
Implementing Equals solely for testing purposes may introduce Equality Pollution: http://xunitpatterns.com/Test%20Logic%20in%20Production.html#Equality Pollution
Mark Seemann
I fixed the Equals override and my example test works. So, is it just good practice to override the GetHashCode() method or is it necessary for some other reason? Thanks!
K-Bell
The `GetHashCode` implementation needs to agree with `Equals`: if two objects are the same, they must have the same hash code. (Two objects can have the same hash code even if they're different, but if different objects have the same hash code, `Equals` must return false.)
Tim Robinson
+2  A: 

In order to determine if 2 collections are equal NUnit must eventually compare the values within the collection. In this case the values are of type ExampleClass which is a class. It does not implement any equality testing (such as overriding Equals and GetHashCode) so NUnit will eventually do a reference comparison. This will fail as each collection contains different instances of Example even though the fields have the same values.

You could fix this by adding the following to the ExampleClass

public override bool Equals(object o) {
  var other = o as ExampleClass;
  if ( other == null ) { return false; }
  return this.Description == other.Description
    && this.SKU == other.SKU
    && this.Price == other.Price
    && this.Qty == other.Qty;
}

public override int GetHashCode() { return 1; }

Note: I chose the value 1 for GetHashCode because this is a mutable type and the only truly safe return value for GetHashCode on a mutable type is a constant. If you intend to use this as a key in a Dictionary<TKey,TValue> though you will want to revisit this.

JaredPar
Thanks JaredPar!
K-Bell