FluentAssertions中BeEquivalentTo()判定相等字符串长度不同问题
JSON字符串对比长度不一致问题解决
问题现象
单元测试中,序列化生成的JSON与预期字符串视觉完全一致,但FluentAssertions 3.1.2报告两者长度分别为351和355,导致测试失败。
核心原因
你编写的expected字符串错误使用了双重大括号{{和}}——这是C#字符串插值的转义语法(用于在插值字符串中表示单个大括号),但在普通const字符串中,{{会被解析为两个{字符,}}会被解析为两个}字符。而Newtonsoft.Json序列化生成的JSON只有单层大括号{},两者的字符数量差正好对应多出来的4个括号(355-351=4)。
解决方案
1. 修正预期字符串写法
将预期字符串中的所有{{替换为{,}}替换为},确保与序列化输出的JSON结构一致:
const string expected = "{\"id\":2,\"distributionSettings\":{\"groupIds\":[777]},\"name\":\"TestApp\",\"displayVersion\":\"1.0.2\",\"primaryVersion\":\"1.0.2\",\"dmPartitionId\":1,\"dmPartitionDistributionType\":\"NONE\",\"dmPartitionDistributionReason\":\"MANUAL\",\"enableReviews\":true,\"enableRatings\":true,\"repushApp\":false,\"inheritCustomAttributes\":false,\"appType\":\"IN_HOUSE\",\"platformType\":\"ANDROID\"}";
2. 改用更可靠的对比方式
避免直接对比字符串,推荐以下两种更稳定的方案:
- 反序列化为对象对比:将JSON字符串转为目标DTO类实例,对比对象属性而非字符:
var actualDto = JsonConvert.DeserializeObject<YourAppDto>(jsonContent); var expectedDto = JsonConvert.DeserializeObject<YourAppDto>(expected); actualDto.Should().BeEquivalentTo(expectedDto);
- 升级FluentAssertions使用JSON断言:如果能升级到FluentAssertions 5.x及以上版本,可直接使用专门的JSON等价断言:
jsonContent.Should().BeEquivalentJson(expected);
3. 排查隐藏字符(可选)
若修正后仍有问题,可输出两个字符串的每个字符编码值,排查不可见字符差异:
// 输出实际字符串的字符编码 foreach (char c in jsonContent) Console.WriteLine($"字符: '{c}',编码: {(int)c}"); // 输出预期字符串的字符编码 foreach (char c in expected) Console.WriteLine($"字符: '{c}',编码: {(int)c}");
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

