解决HTML实体移除问题: 转普通空格及单元测试适配
解决HTML实体解码与编码不一致导致的单元测试失败问题
你遇到的核心问题是 被HtmlDecode解码后得到的是非断空格(U+00A0,十六进制显示为A0),而你预期的是普通空格(U+0020)。数据库的SQL_Latin1_General_CP1_CI_AI排序规则中,非断空格和普通空格的存储/处理逻辑有差异,而你手动编写的测试用例用的是普通空格,这就直接导致了断言失败。下面针对你的两个问题逐一解答:
1. 如何让单元测试通过?
有两种实用方案,你可以根据业务需求选择:
方案一:调整测试用例的预期值
直接把预期字符串中的普通空格替换为非断空格(在C#中用\u00A0表示),同时修正预期值里的HTML实体错误——HtmlDecode会把<转成<、>转成>,原预期里的实体写法是错误的:
public void StripHtmlTest() { // arrange string html = "<p>This is&nbsp;a very <b>fat, <i>italic</i> and <u>underlined</u> text,<!-- foo bar --> sigh.</p> And 6 < 9 but > 3."; string actual; // 用\u00A0表示非断空格,同时替换掉错误的</> string expected = "This is\u00A0a very fat, italic and underlined text, sigh. And 6 < 9 but > 3."; // act actual = StaticRepository.StripHtml(html); // assert Assert.AreEqual(expected, actual); }
方案二:在StripHtml函数中统一空格格式
如果你的业务逻辑要求所有空格都统一为普通空格,可以在解码后添加替换逻辑,把非断空格转换成普通空格:
public static string StripHtml(string text) { // Remove html entities like &nbsp; text = System.Net.WebUtility.HtmlDecode(text); // 将非断空格替换为普通空格,统一格式 text = text.Replace('\u00A0', ' '); // Init Html Agility Pack var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(text); // Return without html tags return htmlDoc.DocumentNode.InnerText; }
这种方式下,你只需要修正原预期值里的<和>为实际符号即可,不用改动空格部分。
2. 你的测试方式是否正确?
整体思路是合理的,但细节上需要优化以贴合真实场景:
- 测试数据要模拟真实数据库内容:建议直接使用从数据库导出的真实字符串片段作为测试用例,而不是手动拼接——这样能完全避免编码不一致的问题,确保测试场景和生产场景一致。
- 明确编码差异逻辑:
SQL_Latin1_General_CP1_CI_AI对应Windows-1252编码,其中0xA0就是非断空格;而Visual Studio手动输入的字符串默认是UTF-16,普通空格为0x20。测试时要明确这种差异,要么让测试数据匹配数据库编码,要么在函数中统一处理编码差异。 - 添加多场景测试:可以分别测试来自数据库的字符串、手动输入的字符串两种场景,确保函数在不同编码来源下都能返回符合预期的结果。
内容的提问来源于stack exchange,提问作者Leonard
相关产品推荐
相关产品推荐

