如何提取FluentAssertions单元测试中重复的配置?
减少FluentAssertions重复配置的几种实用方案
嘿,这个问题我太熟悉了!每次写单元测试遇到这种重复的断言配置,确实会让代码显得冗余又啰嗦。这里有几个简单又有效的办法,能帮你把这些重复逻辑抽离出来,让测试代码清爽不少:
方法1:创建扩展方法(最推荐,复用性拉满)
你可以给EquivalencyAssertionOptions<T>写一个专属的扩展方法,把那些重复的排除规则全部封装进去。这样每次需要用的时候,直接调用这个方法就行,代码瞬间简洁很多。
假设你的实体类型是YourEntityType(记得换成你实际的类型),扩展方法可以这么写:
public static class FluentAssertionsExtensions { public static EquivalencyAssertionOptions<YourEntityType> IgnoreVersioningFields( this EquivalencyAssertionOptions<YourEntityType> options) { return options .Excluding(x => x.Id) .Excluding(x => x.Status) .Excluding(x => x.Stale) .Excluding(x => x.Body) .Excluding(x => x.CreatedBy) .Excluding(x => x.UpdatedBy); } }
之后你的测试代码就可以简化成这样:
// version3应该是version2的副本,仅存在部分差异 version3.Data.ShouldBeEquivalentTo(version2, option => option .IgnoreVersioningFields(), "because version3 is version2 updated"); // version4应该是version3的副本,仅存在部分差异 version4.Data.ShouldBeEquivalentTo(version3, option => option .IgnoreVersioningFields(), "because version4 is version3 updated");
如果你的项目里有多种实体类型都需要排除这些字段,还可以写个泛型版本的扩展方法,适配更多场景:
public static class FluentAssertionsExtensions { public static EquivalencyAssertionOptions<T> IgnoreCommonVersioningFields<T>( this EquivalencyAssertionOptions<T> options) { return options .Excluding(x => x.Id) .Excluding(x => x.Status) .Excluding(x => x.Stale) .Excluding(x => x.Body) .Excluding(x => x.CreatedBy) .Excluding(x => x.UpdatedBy); } }
方法2:预定义配置委托(轻量型复用)
如果不想写扩展方法,或者只需要在单个测试类里复用这些配置,你可以提前定义一个静态委托,每次使用的时候直接传入即可:
// 在你的测试类里定义静态配置委托 private static readonly Action<EquivalencyAssertionOptions<YourEntityType>> _versioningEquivalenceConfig = option => option .Excluding(x => x.Id) .Excluding(x => x.Status) .Excluding(x => x.Stale) .Excluding(x => x.Body) .Excluding(x => x.CreatedBy) .Excluding(x => x.UpdatedBy); // 测试代码里直接调用这个委托 version3.Data.ShouldBeEquivalentTo(version2, _versioningEquivalenceConfig, "because version3 is version2 updated"); version4.Data.ShouldBeEquivalentTo(version3, _versioningEquivalenceConfig, "because version4 is version3 updated");
这种方式不用额外写扩展类,适合小范围的复用场景。
方法3:全局默认配置(谨慎使用)
如果你的整个测试项目里,绝大多数等价性断言都需要排除这些字段,那可以考虑配置FluentAssertions的全局默认规则:
// 在测试项目的初始化代码中(比如AssemblyInitialize标记的方法) FluentAssertions.AssertionOptions.AssertEquivalencyUsing(options => { return options .Excluding(x => x.Id) .Excluding(x => x.Status) .Excluding(x => x.Stale) .Excluding(x => x.Body) .Excluding(x => x.CreatedBy) .Excluding(x => x.UpdatedBy); });
不过这个方法要谨慎使用——它会影响所有测试的等价性断言,如果某个测试需要包含这些字段,就得额外显式覆盖全局配置,所以只适合全局统一规则的场景。
内容的提问来源于stack exchange,提问作者Jevon Kendon
相关产品推荐
相关产品推荐

