How to use Exclude in FluentAssertions for propert

2019-03-14 08:19发布

I have two classes:

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;}
}

I want to use fluent assertions to compare to ClassA instances. However I want to ignore the IDs (because the IDs will have been assigned after the save).

I know I can do this:

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

Which I can obviously repeat for each ClassB in the collection. However I'm looking for a way to exclude the all the IDs (rather than doing an exclude for each element).

I've read this question however if I remove the [0] indexers the assertions fail.

Is this possible?

5条回答
2楼-- · 2019-03-14 08:50

The easiest way is:

expected.ShouldBeEquivalentTo(actual, config => config.ExcludingMissingMembers());
查看更多
做自己的国王
3楼-- · 2019-03-14 09:00

Based on RegEx match idea from Dennis Doomen‘s answer I was able to make it working

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

Difference with Dennis answer: passing su.SelectedMemberPath, double back slashes to escape square brackets.

查看更多
Viruses.
4楼-- · 2019-03-14 09:01

What about?

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

Or you could do a RegEx match on the property path, such as

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

I actually like that last one, but the regex stuff makes it a bit difficult to read. Maybe I should extend ISubjectInfo with a method to match the path against a wildcard pattern, so that you can do this:

expected.ShouldBeEquivalentTo(actualA, options => options
  .Excluding(su => su.PathMatches("Children[*].ID")));
查看更多
We Are One
5楼-- · 2019-03-14 09:02

Simple way would be to set assertions on collection directly, combined with its exclusion on ClassA equivalency assertion:

expectedA.ShouldBeEquivalentTo(expectedB,
   o => o.Excluding(s => s.PropertyInfo.Name == "Children"));
expectedA.Children.ShouldBeEquivalentTo(expectedB.Children,
   o => o.Excluding(s => s.PropertyInfo.Name = "Id"));
查看更多
叼着烟拽天下
6楼-- · 2019-03-14 09:11

I've just come across a similar problem and the latest version of FluentAssertions has changed things a bit.

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))
  );

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

查看更多
登录 后发表回答