代码之家  ›  专栏  ›  技术社区  ›  Liath Marco

如何在FluentAssertions中对集合中的属性使用Exclude?

  •  76
  • Liath Marco  · 技术社区  · 10 年前

    我有两节课:

    public class ClassA
    {
      public int? ID {get; set;}
      public IEnumerable<ClassB> Children {get; set;}
    }
    
    public class ClassB
    {
      public int? ID {get; set;}
      public string Name {get; set;}
    }
    

    我想使用流畅的断言与ClassA实例进行比较。但是,我想忽略ID(因为ID将在保存后分配)。

    我知道我可以做到:

    expectedA.ShouldBeEquivalentTo(actualA, options => options.Excluding(x => x.PropertyPath == "Children[0].ID"));
    

    显然,我可以为集合中的每个ClassB重复这一点。然而,我正在寻找一种排除所有ID的方法(而不是对每个元素进行排除)。

    我读过了 this question 但是,如果我删除[0]索引器,断言将失败。

    这可能吗?

    11 回复  |  直到 10 年前
        1
  •  66
  •   superjos    7 年前

    那么...怎么样

    expected.ShouldBeEquivalentTo(actualA, options => options.Excluding(su => 
       (su.RuntimeType == typeof(ClassB)) && (su.PropertyPath.EndsWith("Id")));`
    

    或者可以在属性路径上执行RegEx匹配,例如

    expected.ShouldBeEquivalentTo(actualA, options => options.Excluding(su => (Regex.IsMatch
       ("Children\[.+\]\.ID"));
    

    我其实很喜欢最后一个,但正则表达式的东西让它有点难读。也许我应该延长 ISubjectInfo 使用方法将路径与通配符模式匹配,这样您就可以执行以下操作:

    expected.ShouldBeEquivalentTo(actualA, options => options
      .Excluding(su => su.PathMatches("Children[*].ID")));
    
        2
  •  37
  •   Nick Randell    9 年前

    我刚刚遇到了一个类似的问题,最新版本的FluentAssessions有点改变。

    我的对象包含其他对象的字典。字典中的对象包含我要排除的其他对象。我的场景是测试Json序列化,其中我忽略了某些财产。

    这对我有用:

    gotA.ShouldBeEquivalentTo(expectedB , config => 
      config
        .Excluding(ctx => ctx.SelectedMemberInfo.MemberType == typeof(Venue))
        .Excluding(ctx => ctx.SelectedMemberInfo.MemberType == typeof(Exhibit))
        .Excluding(ctx => ctx.SelectedMemberInfo.MemberType == typeof(Content))
        .Excluding(ctx => ctx.SelectedMemberInfo.MemberType == typeof(Survey))
        .Excluding(ctx => ctx.SelectedMemberInfo.MemberType == typeof(Media))
      );
    

    花了一些时间来研究如何做,但它真的很有用!

        3
  •  16
  •   k.m    10 年前

    简单的方法是直接在集合上设置断言,并将其排除在 ClassA 等效性断言:

    expectedA.ShouldBeEquivalentTo(expectedB,
       o => o.Excluding(s => s.PropertyInfo.Name == "Children"));
    expectedA.Children.ShouldBeEquivalentTo(expectedB.Children,
       o => o.Excluding(s => s.PropertyInfo.Name = "Id"));
    
        4
  •  13
  •   Bouke Versteegh clauziere    2 年前

    这由以下各项支持 FluentAssertions 6.7

    actualA.Should().BeEquivalentTo(expectedA, options =>
        options
           .For(a => a.Children)
           .Exclude(b => b.ID));
    
        5
  •  10
  •   Aleksei    3 年前

    这里有一些有效的答案,但我添加了另一个不涉及字符串类型表达式的答案。

    expectedA.ShouldBeEquivalentTo(expectedB, o => o.Excluding(s => s.Children));
    expectedA.Children.ShouldBeEquivalentTo(expectedB.Children, o => o.Excluding(s => s.Id));
    
        6
  •  5
  •   wondra    3 年前

    这个 ShouldBeEquivalentTo 为了获得 accepted answer 您可以使用 Excluding 过载 IMemberInfo.SelectedMemberPath 而是:

    expected.Should().BeEquivalentTo(actualA, options => 
        options.Excluding((IMemberInfo mi) => mi.SelectedMemberPath.EndsWith("ID")));
    
        7
  •  4
  •   Michael Freidgeim    6 年前

    基于RegEx匹配思想 Dennis Doomen‘s answer 我能让它工作

    expected.ShouldBeEquivalentTo(actualA, options =>
      options.Excluding(su => 
         (Regex.IsMatch(su.SelectedMemberPath, "Children\\[.+\\].ID"));
    

    与丹尼斯的回答不同:通过su.SelectedMemberPath,双反斜杠转义方括号。

        8
  •  3
  •   Tamás Lévai    2 年前
    actual.Should().BeEquivalentTo(expected,
      assertionOptions => assertionOptions
        .Excluding(x => x.CreationTimestamp))
    

    但是,如果您使用结构和类重写等于,则应将默认值与ComparingByMembers进行比较 https://fluentassertions.com/objectgraphs/#value-types

    actual.Should().BeEquivalentTo(expected,
      assertionOptions => assertionOptions
        .Excluding(x => x.CreationTimestamp)
        .ComparingByMembers<T>())
    
        9
  •  1
  •   cSteusloff    6 年前

    最简单的方法是:

    expected.ShouldBeEquivalentTo(actual, config => config.ExcludingMissingMembers());
    
        10
  •  1
  •   Alan Machado    3 年前

    我觉得语法是这样的

           actual.Should().BeEquivalentTo(
            expected, 
            config => config.Excluding(o => o.Id).Excluding(o => o.CreateDateUtc) });
    
        11
  •  0
  •   Artiom    4 年前

    可以传递表达式列表的扩展类

    public static class FluentAssertionsExtensions {
        public static EquivalencyAssertionOptions<T> ExcludingNextProperties<T>(
            this EquivalencyAssertionOptions<T> options,
            params Expression<Func<T, object>>[] expressions) {
            foreach (var expression in expressions) {
                options.Excluding(expression);
            }
    
            return options;
        }
    }
    

    用法

    actual.Should().BeEquivalentTo(expected, 
                config => config.ExcludingNextProperties(
                    o => o.Id, 
                    o => o.CreateDateUtc))