在 Fluent 断言中排除未初始化 (null) 的属性

Posted

技术标签:

【中文标题】在 Fluent 断言中排除未初始化 (null) 的属性【英文标题】:Exclude uninitialized (null) properties in Fluent assertion 【发布时间】:2012-08-26 18:04:33 【问题描述】:

在 FluentAssertions 中,我可以使用 AllProperties.But(obj => obj.property_I_do_not_want) 从比较断言中删除特定属性,这在我知道要忽略的属性的名称时很好,但在我的情况下我只想忽略未初始化的属性。现在我愿意忽略一个等于 null 但如果有一个解决方案也排除了设置为默认值的原语,那将更加方便。

我开始尝试为PropertyAssertions 类编写扩展方法,但不知道如何创建一个包含Expression<T>IEnumerable<Expression<T>>,用于访问要忽略的每个属性以传递给@987654325 @方法。

【问题讨论】:

【参考方案1】:

如果您愿意尝试 2.0 测试版,您可以在新的 ShouldBeEquivalentTo() API 中使用 lambda 来排除某些属性,如下所示:

subject.ShouldBeEquivalentTo(expected, options =>
    options.Excluding(ctx => ctx.PropertyPath == "Level.Level.Text"));

如果需要,您甚至可以将其封装在自定义规则(实现 ISelectionRule 的类)中,如下所示:

subject.ShouldBeEquivalentTo(expected, options => 
    options.Using(new ExcludeUninitializedProperties()));

事实上,您甚至可以通过覆盖创建初始选项的工厂方法,将其设为特定类型的默认值:

EquivalencyAssertionOptions<TSubject>>.Default = () =>    
    EquivalencyAssertionOptions<TSubject>>.Default.Using(new ExcludeUninitializedProperties())

【讨论】:

这个答案是一个巨大的帮助,但我需要进一步的帮助。我已经在使用 2.0 beta 来支持 MBUnit,但似乎没有用于 Default 属性的“使用”方法,如您上一个代码 sn-p 中提到的那样。不幸的是,我需要覆盖默认值,因为我在问题中遗漏的是我正在使用不采用 EquivalencyAssertionOptions 的 ShouldContainInOrder() 运行两个列表之间的比较。 它位于 FluentAssertions.Equivalency 命名空间中。但它不适用于 ShouldContainInorder() 扩展方法,因为它不是基于相同的引擎。 嗨@DennisDomen,ExcludeUninitializedProperties 是否仍然存在于版本 3.2.1.0 中似乎找不到它。 嗨@AdeAlejo。这只是创建自定义 ISelectionRule 并在断言中使用它的示例。 是的,你在我的理论中发现了一个空白;-)。相反,您可以实现IAssertionRule,如果相关属性未初始化,则只需返回true。这应该可以防止调用任何其他断言。

以上是关于在 Fluent 断言中排除未初始化 (null) 的属性的主要内容,如果未能解决你的问题,请参考以下文章

Fluent 断言命名空间无法识别

C# fluent 断言检查结果为 bool

Fluent 断言 PropertyInfo BeDecoratedWith

使用 Fluent Assertions 库的多个断言

将枚举与自定义 Fluent 断言等效步骤进行比较

如果使用 Fluent Assertions 的顺序不同,如何断言两个列表不等价