FluentAssertions - 当属性属于不同类型时,应该()。BeEquivalentTo()

问题描述 投票:1回答:1

如何比较具有相同名称但不同类型的属性的对象?

public class A
{
    public Guid Id { get; set; }
}

public class B
{
    public string Id { get; set; }
}

public static B Map(A a){
    return new B { Id = a.Id.ToString() };
}

版本1:

void Main()
{
    A a = new A { Id = Guid.NewGuid() };
    B b = Map(a);

    b.Should().BeEquivalentTo(a);
}

这会产生以下错误:

AssertionFailedException:预期成员Id为{ff73e7c7-21f0-4f45-85fa-f26cd1ecafd0},但找到“{ff73e7c7-21f0-4f45-85fa-f26cd1ecafd0}”。

文档建议使用Equivalence Comparison Behavior可以实现自定义属性断言规则

版本2:

void Main()
{
    A a = new A { Id = Guid.NewGuid() };
    B b = Map(a);

    b.Should().BeEquivalentTo(a, 
        options => options
            .Using<Guid>(ctx => ctx.Subject.Should().Be(ctx.Expectation))
            .WhenTypeIs<Guid>());
}

但如果属性不是同一类型,它会产生运行时异常。

AssertionFailedException:来自subject的预期成员Id是System.Guid,但是找到了System.String。

有任何想法吗?

c# unit-testing fluent-assertions
1个回答
3
投票

以下是比较具有不同类型的同名成员的对象的两种方法。

第一种方法是指定名为Id的成员之间的等效性

A expected = new A { Id = Guid.NewGuid() };
B actual = Map(expected);

actual.Should().BeEquivalentTo(expected,
    options => options
    .Using<object>(ctx => ctx.Subject.Should().Be(ctx.Expectation.ToString()))
    .When(info => info.SelectedMemberPath.EndsWith("Id")));

第二种方法使用来自DifferentObjectsEquivalencyStephttps://stackoverflow.com/a/47947052/1087627和你自己的Map函数。然后它将A的实例转换为B,现在很容易比较。

AssertionOptions.AssertEquivalencyUsing(c => 
    c.Using(new DifferentObjectsEquivalencyStep<A, B>(Map)));

A expected = new A { Id = Guid.NewGuid() };
B actual = Map(expected);

actual.Should().BeEquivalentTo(expected);

关于它有一个开放的issue

© www.soinside.com 2019 - 2024. All rights reserved.