FluentAssertions:使用Should().BeEquivalentTo()如何排除字典键比较?
解决FluentAssertions中忽略字典键、仅比较值的问题
嘿,我完全懂你遇到的这个麻烦——当字典的键是动态生成的唯一ID时,默认的BeEquivalentTo()会死死盯着键的匹配度,可你真正关心的是值的内容对不对。之前用Excluding(e => e.KeyValuePair.Keys)没用是正常的,因为这种写法根本没命中正确的配置点,得换个思路:给字典类型定制等价性比较规则才行。
核心解决方案:替换字典的比较逻辑
我们要告诉FluentAssertions:遇到字典类型时,别管键是什么,只比较值的集合。这里分两种场景:
1. 全局对所有字典生效
如果你的对象里所有字典都需要忽略键、只比值,可以直接针对IDictionary类型配置全局规则:
actualObject.Should().BeEquivalentTo(expectedObject, options => options.Using<IDictionary>(ctx => { // 提取两个字典的值集合,直接比较值的等价性 ctx.Subject.Values.Should().BeEquivalentTo(ctx.Expectation.Values); }) .WhenTypeIs<IDictionary>() // 对所有实现IDictionary的类型应用此规则 );
2. 仅针对特定字典属性生效
如果只想处理MyDictionary1、MyDictionary2这类指定的字典属性,就用ForMember单独配置:
actualObject.Should().BeEquivalentTo(expectedObject, options => options .ForMember(x => x.MyDictionary1, cfg => cfg.Using(ctx => { var actualValues = ((Dictionary<string, YourValueType>)ctx.Subject).Values; var expectedValues = ((Dictionary<string, YourValueType>)ctx.Expectation).Values; actualValues.Should().BeEquivalentTo(expectedValues); })) .ForMember(x => x.MyDictionary2, cfg => cfg.Using(ctx => { var actualValues = ((Dictionary<string, YourValueType>)ctx.Subject).Values; var expectedValues = ((Dictionary<string, YourValueType>)ctx.Expectation).Values; actualValues.Should().BeEquivalentTo(expectedValues); })) );
这里注意把YourValueType换成你字典里值的实际类型,比如UserInfo、OrderDetail之类的。
为什么之前的方法无效?
你之前用的Excluding(e => e.KeyValuePair.Keys)逻辑不对:
KeyValuePair不是你对象的直接属性,FluentAssertions找不到这个成员路径- 键是字典结构的核心部分,默认比较会检查键的存在和匹配,单纯“排除”键的成员根本绕不开这个逻辑,必须替换整个字典的比较规则才行。
内容的提问来源于stack exchange,提问作者FSatmar
相关产品推荐
相关产品推荐

