如何为FluentAssertions指定类型全局配置ShouldBeEquivalentTo默认规则?
为FluentAssertions的复杂对象图设置全局类型默认断言规则
你遇到的问题是自定义的BeEquivalentTo扩展仅作用于根对象,嵌套的同类型属性不会继承该规则。要实现所有同类型实例(包括嵌套对象)统一应用断言规则,可以利用FluentAssertions的全局等价性配置,无需在每个测试中重复编写规则。
解决方案:全局配置AssertionOptions
在测试项目的初始化逻辑中(比如测试程序集的AssemblyInitialize方法、xUnit的ICollectionFixture初始化代码)添加全局规则:
using FluentAssertions; using FluentAssertions.Equivalency; // 全局配置,作用于整个测试项目的所有等价性断言 AssertionOptions.AssertEquivalencyUsing(options => { // 基础全局规则(可根据需求调整) options.RespectingRuntimeTypes(); // 为Inner类型设置专属规则:排除Two属性 options.ForType<Inner>(innerConfig => innerConfig.Excluding(prop => prop.Two)); return options; });
为什么这能解决问题?
该全局配置会告知FluentAssertions:任何时候比较Inner类型(包括继承它的Outer、嵌套在其他对象中的Inner实例),都会自动应用排除Two属性的规则。
此时你无需修改原有测试代码,直接运行即可通过:
new Outer { One = "1", Two = "2", Inner = new Inner { One = "inner.1", Two = "inner.2" } }.Should() .BeEquivalentTo(new Outer { One = "1", Two = "3", Inner = new Inner { One = "inner.1", Two = "inner.3" } });
替代方案:自定义扩展中递归应用规则
如果不想使用全局配置,也可以修改自定义扩展,让规则递归作用于整个对象图:
public static class InnerAssertionsExtensions { public static AndConstraint<ObjectAssertions> BeEquivalentToWithInnerRules<T>(this ObjectAssertions assertions, T expectation) { return assertions.BeEquivalentTo(expectation, c => c.RespectingRuntimeTypes() .ForType<Inner>(innerConfig => innerConfig.Excluding(r => r.Two))); } }
调用时使用该扩展方法即可:
new Outer { ... }.Should().BeEquivalentToWithInnerRules(new Outer { ... });
但全局配置更适合你这种大量复用相同基类型的场景,无需每次测试都手动调用自定义扩展。
内容的提问来源于stack exchange,提问作者Lodewijk
相关产品推荐
相关产品推荐

