我可以告诉FluentAssertions在使用BeEquivalentTo时忽略Equals方法吗?

9

我有一个简单的类,有两个属性和重写的Equals方法:

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);
    }
}

现在我创建了一个简单的测试,其中Id值相同,但Name值不同。
[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
}

我从文档中了解到,BeEquivalentTo() 方法默认使用 Equals() 方法进行比较,但我还没有找到一种方法可以覆盖该方法,使实例通过其属性值进行比较。
在 FluentAssertions 中有其他方法可以实现这个功能吗?
[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);
}
2个回答

13
你只需要像这样在EquivalencyAssertionOptions中为你的类型覆盖相等比较器即可:

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


2
如果 Person 有一个 Company 属性,我们是否也想在那里强制进行成员比较?这个设置能否在全局级别上应用,以便影响整个对象图? - Zoltán Tamási

1
你也可以使用动态对象。
[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);
}

如果您需要嵌套对象比较,也请对它们使用动态方法。
dynamic expected = new
{
    Id = 123,
    Name = "John Doe",
    City = new {
        Id = 456,
        Name = "Paris"
        Country = new {
            Id = 789,
            Name = France
        }
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接