流利的断言:字典应该是等效的,以排除字典值上的属性

Posted

技术标签:

【中文标题】流利的断言:字典应该是等效的,以排除字典值上的属性【英文标题】:Fluent Assertion: Dictionary Should BeEquivalentTo Excluding Property on Dictionary Value 【发布时间】:2021-02-22 21:41:06 【问题描述】:

我有一个名为 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);

我希望断言需要类似于以下内容,但我无法正确获取 Excluding 方法中的 lambda。

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

【问题讨论】:

【参考方案1】:

首先,如果您只是想过滤掉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 的成员。

【讨论】:

以上是关于流利的断言:字典应该是等效的,以排除字典值上的属性的主要内容,如果未能解决你的问题,请参考以下文章

如何使用流利的断言结合集合和属性断言?

流利的断言应该大于总是通过

流利的断言应该AllBeEquivalentTo

Meteor:我应该如何更新用户集合以在对象/字典中包含一个新属性?

如何使用流利的断言比较列表?

流利的断言 - 如何在类型检查后正确链接