升级Fluent Assertions至5.3.0后,匿名类型下BeEquivalentTo排除字段报错
解决Fluent Assertions 5.x中匿名类型等价比较时Excluding方法报错的问题
我刚帮人排查过类似的升级坑,这是因为Fluent Assertions从4.x升级到5.x时,重构了等价比较的成员选择API,导致原来针对强类型的表达式写法在匿名类型场景下直接失效了。
问题根源
在FA4.19.3里,Excluding(o => o.Context)这种写法是基于目标类型的强类型表达式来选要排除的成员。但你这里预期值用了匿名类型,编译器会把表达式里的o推断成这个匿名类型(而不是实际返回结果的类型),可匿名类型根本没有Context属性——FA5重构后改用IMemberInfo传递成员信息,所以直接写o.Context就会报错,因为IMemberInfo压根没有这个属性或扩展方法。
解决方案
我们换一种方式指定要排除的成员,通过IMemberInfo的Name属性来匹配,不管是强类型还是匿名类型都能正常工作:
var result = await MyClass.GetResultAsync(); result.Should().BeEquivalentTo( new { StatusCode = 200, Exception = (Exception)null }, options => options.Excluding(member => member.Name == "Context") );
补充细节:
- 我把旧的
ShouldBeEquivalentTo改成了FA5推荐的链式写法Should().BeEquivalentTo(),虽然旧方法可能还有兼容,但新版本更推荐这种风格,也能避免一些隐性的API兼容问题。 - 如果需要更精确地控制只排除**源对象(也就是
result)**的Context成员,可以用ExcludingSource:
这在预期对象和源对象有同名不同含义的成员时会更有用,不过你的场景里预期匿名类型没有options => options.ExcludingSource(member => member.Name == "Context")Context,两种写法效果一致。
为什么这样可行?
FA5的Excluding方法现在接受一个Func<IMemberInfo, bool>参数,通过member.Name我们可以直接匹配到要排除的成员名称,完全绕过了强类型表达式的限制,完美适配匿名类型的对比场景。
内容的提问来源于stack exchange,提问作者Allan Nielsen
相关产品推荐
相关产品推荐

