C# 如何在集合中的属性的FluentAssertions中使用Exclude?
我有两门课:C# 如何在集合中的属性的FluentAssertions中使用Exclude?,c#,unit-testing,fluent-assertions,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;} } 很明显,我可以对集合中的每个ClassB重复这一点。然而,我正在寻找一种排除所有ID的方法(
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;}
}
很明显,我可以对集合中的每个ClassB重复这一点。然而,我正在寻找一种排除所有ID的方法(而不是对每个元素进行排除)
但是,我已经读过,如果删除[0]索引器,断言将失败
这可能吗?简单的方法是直接在集合上设置断言,并在
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"));
那怎么办
expected.ShouldBeEquivalentTo(actualA, options => options.Excluding(su =>
(su.RuntimeType == typeof(ClassB)) && (su.PropertyPath.EndsWith("Id")));`
或者可以在属性路径上进行正则表达式匹配,例如
expected.ShouldBeEquivalentTo(actualA, options => options.Excluding(su => (Regex.IsMatch
("Children\[.+\]\.ID"));
实际上我喜欢最后一个,但是正则表达式的东西让它有点难读。也许我应该使用一种方法来扩展ISubjectInfo
,使路径与通配符模式相匹配,以便您可以执行以下操作:
expectedA.ShouldBeEquivalentTo(actualA, options => options.Excluding(x => x.PropertyPath == "Children[0].ID"));
expected.ShouldBeEquivalentTo(actualA, options => options
.Excluding(su => su.PathMatches("Children[*].ID")));
我刚刚遇到了一个类似的问题,最新版本的FluentAssertions稍微改变了一些情况 “我的对象”包含其他对象的词典。字典中的对象包含我要排除的其他对象。我的场景是关于测试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))
);
花了一些时间研究如何做,但它真的很有用 最简单的方法是:
expected.ShouldBeEquivalentTo(实际,配置=>config.ExcludingMissingMembers());
基于我的正则表达式匹配思想,我能够让它工作
expected.ShouldBeEquivalentTo(actualA, options =>
options.Excluding(su =>
(Regex.IsMatch(su.SelectedMemberPath, "Children\\[.+\\].ID"));
与Dennis答案的不同之处在于:传递su.SelectedMemberPath,使用双反斜杠来转义方括号。一个扩展类,可以在其中传递表达式列表
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;
}
}
应该等价于
方法现在似乎已经过时,为了获取的路径,您可以使用排除
重载和IMemberInfo。改为选择成员路径
:
expected.Should().BeEquivalentTo(actualA, options =>
options.Excluding((IMemberInfo mi) => mi.SelectedMemberPath.EndsWith("ID")));
我认为语法是这样的
actual.Should().BeEquivalentTo(
expected,
config => config.Excluding(o => o.Id).Excluding(o => o.CreateDateUtc) });
我将把这个标记为答案,因为扩展方法中的正则表达式是我最后使用的方法,在更新版本的FluentAssertions中这有什么变化?我不确定
PropertyPath
是否仍然存在。我尝试了两个选项都没有成功,但能够修复RegEx选项以使用当前版本-请参阅。顺便说一句,PropertyPath的新名称是SelectedMemberPathRegex.IsMatch(x.SelectedMemberPath,@“Children\[\d+\]\.ID”)
OP要求排除一些现有(未丢失)成员。我认为Propertyinfo不再存在。SelectedMemberInfo.Name应该这样做。出于价值考虑,您也可以传入一个匿名对象作为自FA 5以来的期望值,并且只包含您关心的属性。不是所有的英雄都会这样做
actual.Should().BeEquivalentTo(
expected,
config => config.Excluding(o => o.Id).Excluding(o => o.CreateDateUtc) });