TortugaGonca
TortugaGonca

Reputation: 31

Why Assert.AreEqual<T> fails with identical objects?

I have a class which contains this attributes:

public class Person
{
    public long Id { get; set; }

    public string Name { get; set; }

    public int? IdCountry { get; set; }
    public virtual Country Country { get; set; }
    public int? IdState { get; set; }
    public virtual State State { get; set; }
}

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class State
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int IdCountry { get; set; }
    public virtual Country Country { get; set; }
}

In a unit test I create 2 objects with the same values

Person expected = new Person()
{
    Name = "blablablbla",
    Id = 1
};
Person actual = PessoaFactory.Create(Name: "blablablbla", Id: 1);
Assert.AreEqual<Person>(expected, actual);

But the Assert.AreEqual throws an exception.

Upvotes: 3

Views: 1472

Answers (5)

Matan Shahar
Matan Shahar

Reputation: 3240

The .Net framework itself doesn't handle deep equality cooperation by default, Assert.AreEqual calls the Equals method on the object which is object.Equals if you didn't override the method. Object.Equals is implementing reference check only. You should implement your own Equals method, for example:

public override bool Equals(object o)
{
    var cast = o as Person;
    if (cast == null) 
        return false; 
    return cast.Id == this.Id;
}

public override int GetHashCode()
{
    return this.Id;
}

For more information you can check this MSDN Doc

Upvotes: 0

MichaC
MichaC

Reputation: 13381

You have two different object references to compare.

Instead use Assert.IsTrue(expected.Id == actual.Id) for example or override Equals and GetHashCode to be able to compare your objects

Upvotes: 2

Daniel A. White
Daniel A. White

Reputation: 190897

Because it is comparing the references not the actual values within it.

Upvotes: 2

Patrick Quirk
Patrick Quirk

Reputation: 23747

You need to override Equals to compare the objects. The default implementation compares references, not values. See the MSDN documentation.

Upvotes: 6

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

Because you need to override Equals and GetHashCode:

public override bool Equals(object o)
{
    if (!(o is Person)) { return false; }
    return ((Person)o).Id == this.Id;
}

public override int GetHashCode()
{
    return this.Id;
}

Assert.AreEqual<T> uses the default comparer for the type. The default comparer for that type is to compare hash codes. The hash codes aren't equal.

Upvotes: 3

Related Questions