如何在FluentAssertions中使用Exclude来获取集合中的属性?

Lia*_*ath 32 c# unit-testing fluent-assertions

我有两节课:

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;}
}
Run Code Online (Sandbox Code Playgroud)

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

我知道我可以这样做:

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

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

我已经读过这个问题但是如果我删除了[0]索引器,断言就会失败.

这可能吗?

Den*_*men 34

关于什么?

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

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

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

我实际上喜欢最后一个,但正则表达式的东西让它有点难以阅读.也许我应该ISubjectInfo使用一种方法来扩展路径与通配符模式匹配,以便您可以这样做:

expected.ShouldBeEquivalentTo(actualA, options => options
  .Excluding(su => su.PathMatches("Children[*].ID")));
Run Code Online (Sandbox Code Playgroud)

  • 在最新版本的FluentAssertions中,这是如何改变的?我不确定`PropertyPath`是否还在那里 (3认同)
  • `Regex.IsMatch(x.SelectedMemberPath, @"Children\[\d+\]\.ID")` (2认同)

Bou*_*egh 26

FluentAssertions 6.7支持此功能

actualA.Should().BeEquivalentTo(expectedA, options =>
    options
       .For(a => a.Children)
       .Exclude(b => b.ID));
Run Code Online (Sandbox Code Playgroud)


Nic*_*ell 22

我刚遇到类似的问题,最新版本的FluentAssertions已经改变了一些东西.

My objects contains dictionaries of other objects. The objects in the dictionaries contain other objects that I want to exclude. The scenario I have is around testing Json serialization where I ignore certain properties.

This works for me:

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))
  );
Run Code Online (Sandbox Code Playgroud)

Took some time to work out how to do it, but it's really useful!

  • 不管怎样,您还可以传入一个匿名对象作为 FA 5 以来的期望,并仅包含您关心的属性。 (2认同)

Ale*_*sei 11

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

expectedA.ShouldBeEquivalentTo(expectedB, o => o.Excluding(s => s.Children));
expectedA.Children.ShouldBeEquivalentTo(expectedB.Children, o => o.Excluding(s => s.Id));
Run Code Online (Sandbox Code Playgroud)


k.m*_*k.m 8

简单的方法是直接在集合上设置断言,并将其排除在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"));
Run Code Online (Sandbox Code Playgroud)

  • 我认为 Propertyinfo 已经不存在了。SelectedMemberInfo.Name 应该这样做。 (4认同)

won*_*dra 8

ShouldBeEquivalentTo方法现在似乎已过时,为了获取已接受答案的路径,您可以使用Excluding重载IMemberInfo.SelectedMemberPath

expected.Should().BeEquivalentTo(actualA, options => 
    options.Excluding((IMemberInfo mi) => mi.SelectedMemberPath.EndsWith("ID")));
Run Code Online (Sandbox Code Playgroud)


小智 7

actual.Should().BeEquivalentTo(expected,
  assertionOptions => assertionOptions
    .Excluding(x => x.CreationTimestamp))
Run Code Online (Sandbox Code Playgroud)

但是如果您使用结构和类覆盖 equals,那么您应该更改与 ComparingByMembers 相比的默认值 https://fluidassertions.com/objectgraphs/#value-types

actual.Should().BeEquivalentTo(expected,
  assertionOptions => assertionOptions
    .Excluding(x => x.CreationTimestamp)
    .ComparingByMembers<T>())
Run Code Online (Sandbox Code Playgroud)