Can I tell FluentAssertions to ignore Equals method when using BeEquivalentTo
Asked Answered
V

2

11

I have a simple class with two properties and the Equals method overridden:

public class Person : IEquatable<Person>
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as Person);
    }

    public bool Equals(Person other)
    {
        return other != null &&
            this.Id.Equals(other.Id);
    }

    public override int GetHashCode()
    {
        return 2108858624 + EqualityComparer<Guid>.Default.GetHashCode(this.Id);
    }
}

Now I created a simple test, where the Id values are the same, but the Name values are different.

[Fact]
public void PersonShouldNotBeEqual()
{
    var guid = Guid.NewGuid();

    var p1 = new Person { Id = guid, Name = "Me" };
    var p2 = new Person { Id = guid, Name = "You" };

    p1.Should().NotBeEquivalentTo(p2); // Fails
}

I understood from the documentation that BeEquivalentTo() uses the Equals() method by default when it is overridden in the class, but I haven't found a way to overrule that so the instances are compared by their property values.

Is it possible to do this in FluentAssertions other then the way below?

[Fact]
public void PersonShouldBeEqual()
{
    var guid = Guid.NewGuid();

    var p1 = new Person { Id = guid, Name = "Me" };
    var p2 = new Person { Id = guid, Name = "You" };

    p1.Id.Should().Be(p2.Id);
    p1.Name.Should().Be(p2.Name);
}
Vendor answered 16/7, 2019 at 7:56 Comment(0)
R
14

You just need to override equality comparer for your type in EquivalencyAssertionOptions like this :

p1.Should().BeEquivalentTo(p2, options => options.ComparingByMembers<Person>())

Resume answered 16/7, 2019 at 8:9 Comment(1)
What if Person had a Company property and we'd want to force member-wise comparison there too? Can this setting be applied somehow on a global level so that the entire object graph gets affected?Darcee
A
1

You can also use dynamic objects.

[Fact]
public void PersonShouldNotBeEqual()
{
    var guid = Guid.NewGuid();

    var p1 = new Person { Id = guid, Name = "Me" };

    dynamic p2 = new { Id = guid, Name = "You" };
    p1.Should().NotBeEquivalentTo(p2);

    dynamic p3 = new { Id = guid, Name = "Me" };
    p1.Should().BeEquivalentTo(p3);
}

If you also need nested object comparison, use dynamic for them too.

dynamic expected = new
{
    Id = 123,
    Name = "John Doe",
    City = new {
        Id = 456,
        Name = "Paris"
        Country = new {
            Id = 789,
            Name = France
        }
    }
};
Atlantis answered 12/1, 2021 at 14:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.