HTML实体解码后字符串与字面量不等,Jest测试失败该如何处理?
问题原因
这是HTML实体解码后得到的特殊Unicode字符和你预期的普通字符编码不一致导致的,和JS字符串特性相关,主要有两个核心差异点:
解码后得到的不是普通半角空格(Unicode编码U+0020),而是不间断空格(Unicode编码U+00A0),二者视觉表现完全一致,但编码值不同,所以Object.is和Jest的toEqual都会判定二者不相等。­解码后得到的是软连字符(Unicode编码U+00AD),这个字符属于不可见控制字符,排版时只有行尾需要折行才会显示为连字符,不需要折行时视觉上完全隐藏,所以你看起来解码结果是foobar,但实际字符串中多了一个U+00AD字符,和测试预期的普通foobar不匹配。
解决方案
根据你的使用场景二选一即可:
场景1:需要保留HTML实体的原始语义
如果业务中需要保留不间断空格的不换行特性、软连字符的折行提示特性,直接修改测试用例的预期值为对应真实编码的字符即可:
it.each([ ['foo bar', 'foo\u00A0bar'], ['foo­bar', 'foo\u00ADbar'], ['foo&bar', 'foo&bar'] ])('should decode html entities', (val, expected) => { expect(decodeHtml(val)).toEqual(expected); })
场景2:只需要普通可打印文本
如果不需要保留这些HTML特殊字符的语义,只需要得到普通文本内容,在解码逻辑后添加一层特殊字符归一化处理即可:
function decodeHtml(html) { // 你原有的解码逻辑 const txt = document.createElement('textarea'); txt.innerHTML = html; let result = txt.value; // 新增特殊字符归一化逻辑 result = result .replace(/\u00A0/g, ' ') // 不间断空格替换为普通空格 .replace(/\u00AD/g, ''); // 移除软连字符 // 其他需要处理的特殊字符也可以在此处添加对应规则 return result; }
修改后你的测试用例和Object.is(decodeHtml(' '), ' ')判断都会正常返回true。
内容的提问来源于stack exchange,提问作者rsmidt
相关产品推荐
相关产品推荐

