首页 > 解决方案 > 如何在 FluentAssertions 中使用方法

问题描述

有时我不得不断言两个列表具有相同的项目。使用流利的断言可以这样完成:

class MyObject { public string MyString {get; set;} }

var o1 = new MyObject { MyString = "1    " }
list1.Add(o1);

var o2 = new MyObject { MyString = "1" }
list2.Add(o2);

list1.Should().BeEquivalentTo(list2)

但有时我希望以不同的方式比较特定属性,如下所示:

list1.Should().BeEquivalentTo(list2, options => options
            .Using<string>(context => context.Subject.TrimEnd().Should().Be(context.Expectation))
            .When<string>( ??????? ));

我努力了:

it => it.SelectedMemberInfo.Name == PropertyNameHere

但是 SelectedMemberInfo 可以为空,并且在为空时会引发异常,我不知道我是否以正确的方式调用它。

更新 1:已尝试,但为空引用异常:

        options => options
        .Using<DateTime>(it => it.Subject.Should().BeCloseTo(DateTime.Now, TimeSpan.FromMinutes(1)))
        .When(it =>
            it != null
            && it.SelectedMemberInfo != null
            && it.SelectedMemberInfo.Name == nameof(Y.X)));

标签: c#.nettestingfluent-assertions

解决方案


要匹配MyString属性,最常用的两种方法是按类型匹配或按路径匹配。

要按类型匹配MyString,请使用WhenTypeIs<string>.

[TestMethod]
public void MatchByType()
{
    var o1 = new MyObject { MyString = "1    " };
    var list1 = new[] { o1 };

    var o2 = new MyObject { MyString = "1" };
    var list2 = new[] { o2 };

    list1.Should().BeEquivalentTo(list2, opt => opt
        .Using<string>(ctx => ctx.Subject.TrimEnd().Should().Be(ctx.Expectation))
        .WhenTypeIs<string>());
}

对于好奇WhenTypeIs<TMemberType>只是一个别名

When(info => info.RuntimeType.IsSameOrInherits(typeof(TMemberType))

要按名称匹配MyString,您可以使用When(e => e.SelectedMemberPath).

SelectedMemberPath定义为

从根对象到当前对象的完整路径,用点分隔。

在这种情况下,根对象是MyObject,所以SelectedMemberPath将是"MyString"。所以这可以写成:

[TestMethod]
public void MatchByName()
{
    var o1 = new MyObject { MyString = "1    " };
    var list1 = new[] { o1 };

    var o2 = new MyObject { MyString = "1" };
    var list2 = new[] { o2 };

    list1.Should().BeEquivalentTo(list2, opt => opt
        .Using<string>(ctx => ctx.Subject.TrimEnd().Should().Be(ctx.Expectation))
        .When(e => e.SelectedMemberPath.EndsWith(nameof(MyObject.MyString))));
}

推荐阅读