流利的断言:字典应等同于排除字典值的属性

问题描述

我有一个名为HandRank的类,该类具有Id属性。 Id属性由我的数据库生成

public class HandRank
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int Rank { get; set; }
}

我有一个名为GetHandRanks的方法,该方法返回一个Dictionary<string,HandRank>

在我的测试中,我正在植入内存数据库。由于Id属性数据库确定,因此我希望将其从断言中排除。

下面是我的测试,但失败,因为未在ExpectedResult中设置Id属性。我之所以没有设置ID,是因为我不知道数据库生成该ID时将是什么。

[Test]
public void test()
{
    // arrange
    var expectedResult = new Dictionary<string,HandRank>
    {
        { "aaa",new HandRank { Rank = 1} },{ "bbb",new HandRank { Rank = 2} }
    };

    // act
    var actualResult = _handRankManager.GetHandRanks();

    // Assert
    actualResult.Should().BeEquivalentTo(expectedResult);
}

我希望断言必须类似于以下内容,但是我无法正确获得Exclusion方法中的lambda。

actualResult.Should().BeEquivalentTo(expectedResult,options => options.Excluding(x => x.Values.Id));

解决方法

首先,如果仅 要过滤掉HandRank.Id,则可以使用以下代码:

actualResult.Should().BeEquivalentTo(expectedResult,opt =>
    opt.Excluding(m => 
        m.SelectedMemberInfo.DeclaringType == typeof(HandRank) 
        && m.SelectedMemberInfo.Name.Equals(nameof(HandRank.Id))
    ));

如果您想在测试的许多部分中使用名为"Id"的属性,那么最好将其带入这样的函数中:

public static EquivalencyAssertionOptions<_> ExcludeId<_>(EquivalencyAssertionOptions<_> opt)
    => opt.Excluding(m => m.SelectedMemberInfo.Name.Equals("Id"));

并按原样使用它:

actual.Should().BeEquivalentTo(expected,ExcludeId);

应对字典,列表,具有较深属性的对象以及任何您能想到的东西起作用。它将忽略所有名为Id的成员。