Jest 27.5.1中不同URL实例为何被toEqual判定为相等?
Jest 27.5.1中URL实例相等性断言失败原因
这个问题是Jest 27版本内置深度相等判断逻辑的已知缺陷导致的:
Jest的toEqual匹配器底层依赖自研的深度相等比较逻辑,在27.5.1版本中,该逻辑没有针对URL这类内置Web API对象做特殊适配:URL实例的核心属性(href、hostname、host、pathname等)全部是定义在原型链上的访问器属性(getter),不属于实例自身的可枚举属性,在测试中打印Object.keys(new URL('http://example.com'))会得到空数组。Jest 27做对象深度对比时,默认只会遍历对象自身的可枚举属性做值比较,不会主动读取原型链上的访问器属性值,因此会把两个不同的URL实例判定为结构完全一致的空对象,最终判定两者相等,导致expect(b).not.toEqual(a)断言失败。
可行解决方案
- 显式比较URL的序列化值:直接对比URL转成字符串后的结果,绕开Jest对对象实例的判断逻辑,这是兼容性最好的方案,不受Jest版本影响,示例代码:
it('should have working URL comparisons', () => { const a = new URL('http://foo.example.com'); const b = new URL('http://bar.example.com'); // 取href属性或者调用toString()效果完全一致,两者都会返回URL的完整字符串 expect(b.href).not.toBe(a.href); });
- 升级Jest版本:升级到Jest 29.x及以上版本,新版Jest的相等性判断逻辑已经适配了URL、URLSearchParams等内置Web API对象,会正确读取核心属性做对比,原有测试代码不需要修改即可正常运行。
- 自定义字段校验:如果暂时无法升级Jest,也可以根据测试需求,手动提取URL需要校验的字段(比如hostname、origin、pathname等)做原始值比较,避免直接对比URL实例对象。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

