0

例如,我有简单的课程

class Person {
   public string Name;
   public string LastName;
   public Person Parent;
   public static int IdCounter = 0;
   public int Id;

   public Person(string name, string lastName, Person parent) {
      Name = name;
      LastName = lastName;
      Parent = parent;
      Id = IdCounter++;
   }
}

在测试中,我想将我从某个地方得到的人与预期的人进行比较,如下所示:

var expectedPerson = new Person ("John","Galecky", new Person("Sheldon", "Cooper", null));
var actualPerson = PersonGenerator.GetCurrentPerson();

我想递归地比较它们,不包括 Id 字段,这对父母也意味着什么

actualPerson.Should().BeEquivalentTo(expectedPerson, (options) =>
            {
                options.Excluding(t => t.Id);
            });

但是 ofc 这仅适用于第一级人员,我如何排除 Parent 和他的 Parent 等的 Id 字段,而 FluentAssertion 可以进入递归(文档中有 10 个级别)?在这个例子中似乎很不合理,但我确实需要这样做,怎么做?

4

1 回答 1

2

要递归排除成员,您必须使用Excluding(Expression<Func<IMemberInfo, bool>> predicate)which 让您模式匹配要排除的成员的路径。

例如你想排除

  • ID
  • 父代号
  • 父.父.Id
  • ...

由于每条路径都以您的结尾,Id您可以使用

Excluding(ctx => ctx.SelectedMemberPath.EndsWith("Id"))
var expectedPerson = new Person("John", "Galecky", new Person("Sheldon", "Cooper", null));
var actualPerson = new Person("John", "Galecky", new Person("Sheldon", "Cooper", null));

actualPerson.Should().BeEquivalentTo(expectedPerson, options =>
    options.Excluding(ctx => ctx.SelectedMemberPath.EndsWith("Id")));

请注意,这是纯字符串匹配。例如,如果另一个成员有一个Id想要包含的属性,您可以使用这种方式来确保它只匹配根 Id 或任何 Parent.Id。

Regex.IsMatch(ctx.SelectedMemberPath, @"^(Parent\.)*Id$")
于 2019-10-30T07:18:23.910 回答