如何在Jest中按顺序比较数组?含基本类型与对象数组示例
在Jest中实现按顺序的数组断言方法
首先得纠正一个小误解:Jest自带的toEqual方法本身就是严格按顺序比较数组的!你想要的按顺序断言其实根本不需要额外自定义方法,直接用原生的toEqual就能实现你举的例子:
// 这两个断言都会顺利通过 expect([1, 2, 3].concat(4)).toEqual([1, 2, 3, 4]); expect([{ value: 1}, { value: 2}, { value: 3 }].concat({ value: 4 })).toEqual([ { value: 1 }, { value: 2 }, { value: 3 }, { value: 4 } ]);
可能你之前搜索到的是Jest里忽略顺序的数组比较方法(比如toContainEqual,或者第三方库的toIncludeSameMembers),所以误以为默认的数组比较都忽略顺序,其实正好相反——toEqual会逐个位置对比数组元素,包括嵌套对象的深度对比,完全符合你要的"按顺序比较"需求。
关于用JSON.stringify实现的可行性
当然可以用JSON.stringify来做对比,但非常不推荐,因为它有不少局限性:
- 无法处理带循环引用的对象,会直接抛出错误
- 对对象的属性顺序敏感(虽然ES6+规范了对象属性的插入顺序,但某些特殊属性的排序在
JSON.stringify中可能不符合预期) - 会把
undefined、NaN、Infinity这类特殊值转成null或者直接忽略,导致错误的断言结果
如果一定要自定义toEqualWithOrder匹配器
如果你只是想要一个语义化的命名匹配器,也可以通过Jest的expect.extend来封装原生的toEqual逻辑:
expect.extend({ toEqualWithOrder(received, expected) { const pass = this.equals(received, expected); const receivedStr = this.utils.printReceived(received); const expectedStr = this.utils.printExpected(expected); if (pass) { return { message: () => `expected ${receivedStr} not to match in order with ${expectedStr}`, pass: true }; } else { return { message: () => `expected ${receivedStr} to match in order with ${expectedStr}, but they differ`, pass: false }; } } }); // 之后就能像你想要的那样调用了 expect([1,2,3].concat(4)).toEqualWithOrder([1,2,3,4]); expect([{value:1}, {value:2}].concat({value:3})).toEqualWithOrder([{value:1}, {value:2}, {value:3}]);
内容的提问来源于stack exchange,提问作者dannyxnda
相关产品推荐
相关产品推荐

