【问题标题】:FluentAssertions - Should().BeEquivalentTo() when properties are of different typeFluentAssertions - Should().BeEquivalentTo() 当属性为不同类型时
【发布时间】:2018-08-09 18:40:17
【问题描述】:

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

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:预期的来自主题的成员 ID 是 System.Guid,但找到了 System.String。

有什么想法吗?

【问题讨论】:

    标签: c# unit-testing fluent-assertions


    【解决方案1】:

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

    第一种方法是指定名为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")));
    

    第二种方法使用来自https://stackoverflow.com/a/47947052/1087627DifferentObjectsEquivalencyStep 和您自己的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

    【讨论】:

    • DifferentObjectsEquivalencyStep 应该作为扩​​展方法添加到 fluentassertion 中!
    • @MichalCiechan 随时在issue tracker 上打开一个关于的问题。我目前正在摆弄另一种方法,您可以在其中编写.Using&lt;string, Guid&gt;(ctx =&gt; ctx.Subject.Should().Be(ctx.Expectation.ToString())).When(info =&gt; info.SelectedMemberPath.EndsWith("Id")))。这应该不那么脆弱,更具表现力。
    猜你喜欢
    • 2013-04-15
    • 2018-08-25
    • 2019-01-21
    • 2021-05-06
    • 2014-11-13
    • 2021-09-02
    • 2019-05-01
    • 2018-08-03
    • 2020-06-09
    相关资源
    最近更新 更多