如何在FluentAssertions中高效排除多属性进行对象对比与差异检查
简化FluentAssertions多排除属性的差异检查
当你用FluentAssertions对比对象图时,如果需要排除大量属性,还要逐个手动断言这些属性的差异或特定值,可以试试以下两种更简洁的方式:
1. 在对象图对比配置中直接嵌入断言逻辑
不用分开写BeEquivalentTo和单独的属性断言,直接在配置里通过Using+When把排除属性的校验逻辑整合进去:
order.Should().BeEquivalentTo(anotherOrder, options => options // 先排除不需要参与对象图对比的属性 .Excluding(o => o.Customer.Name) .Excluding(o => o.OrderNumber) .Excluding(o => o.ShippingAddress.ZipCode) // 针对Customer.Name定义断言:和对比对象不同且等于"John" .Using<object>(ctx => ctx.Subject.Should().NotBe(ctx.Expectation).And.Be("John")) .When(o => o.Customer.Name) // 针对OrderNumber定义断言:大于对比对象的订单号 .Using<int>(ctx => ctx.Subject.Should().BeGreaterThan(ctx.Expectation)) .When(o => o.OrderNumber) // 针对ZipCode定义断言:不为空 .Using<string>(ctx => ctx.Subject.Should().NotBeNullOrEmpty()) .When(o => o.ShippingAddress.ZipCode));
这种方式把所有逻辑集中在一处,避免代码分散,可读性更强。
2. 批量管理排除属性与断言逻辑
如果排除属性和对应的断言逻辑较多,可以把它们封装成集合,先执行对象图对比,再批量执行断言:
// 定义一个集合,存储要排除的属性选择器和对应的断言逻辑 var excludedPropertyChecks = new List<( Expression<Func<Order, object>> PropertySelector, Action<Order, Order> AssertionLogic )> { (o => o.Customer.Name, (o1, o2) => o1.Customer.Name.Should().NotBe(o2.Customer.Name).And.Be("John")), (o => o.OrderNumber, (o1, o2) => o1.OrderNumber.Should().BeGreaterThan(o2.OrderNumber)), (o => o.ShippingAddress.ZipCode, (o1, o2) => o1.ShippingAddress.ZipCode.Should().NotBe(o2.ShippingAddress.ZipCode)) }; // 执行对象图对比,批量排除指定属性 order.Should().BeEquivalentTo(anotherOrder, options => options.ExcludingMany(excludedPropertyChecks.Select(item => item.PropertySelector))); // 批量执行每个排除属性的断言 foreach (var (_, assertion) in excludedPropertyChecks) { assertion(order, anotherOrder); }
注意:ExcludingMany是FluentAssertions较新版本提供的方法,如果你的版本不支持,可以用链式调用.Excluding(),或者自己写个扩展方法来批量排除。
内容的提问来源于stack exchange,提问作者user246392
相关产品推荐
相关产品推荐

