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?
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")));
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!
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"));
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.
The easiest way is:
expected.ShouldBeEquivalentTo(actual, config => config.ExcludingMissingMembers());