使用Jest与TypeScript测试Array.prototype.reverse是否被调用的问题
问题描述
我正在测试一个包含Array.prototype.reverse调用的函数,但无法正确使用jest.spyOn监听该函数,参数设置始终存在问题。
待测试代码
const parentFunction = (param) => { let someArray = []; switch(param) { case 1: someArray = childFunction(); break; default: break; } return someArray; } const childFunction = () => { const anotherArray = [1, 2, 3, 4]; const reversedArray = anotherArray.reverse(); return reversedArray; }
测试代码
test("if the reverse function has been called", () => { jest.spyOn(Array, "reverse"); // 编辑器报错 jest.spyOn(Array.prototype, "reverse"); // 编辑器同样报错 parentFunction(1); expect(Array.reverse).toHaveBeenCalled(); expect(Array.prototype.reverse).toHaveBeenCalled(); });
报错信息
No overload matches this call. Overload 1 of 4, '(object: any[], method: FunctionPropertyNames<any[]>): never', gave the following error. Argument of type 'string' is not assignable to parameter of type 'FunctionPropertyNames<any[]>'. Overload 2 of 4, '(object: any[], method: ConstructorPropertyNames<any[]>): never', gave the following error. Argument of type 'string' is not assignable to parameter of type 'ConstructorPropertyNames<any[]>'.
请问是否缺少特殊的测试导入?有什么解决建议吗?
解决方案
1. 类型断言解决TS类型报错
报错是TypeScript类型检查导致的,reverse是Array.prototype上的原型方法,直接传字符串会触发类型不匹配。可以用类型断言告诉TS该方法名合法:
const reverseSpy = jest.spyOn(Array.prototype, 'reverse' as keyof Array<any>);
2. 正确的测试断言写法
测试时要监听Array.prototype.reverse,并且断言时要使用创建的spy实例,而非直接断言原型方法:
test("if the reverse function has been called", () => { // 创建spy并处理类型 const reverseSpy = jest.spyOn(Array.prototype, 'reverse' as keyof Array<any>); parentFunction(1); // 用spy实例断言调用情况 expect(reverseSpy).toHaveBeenCalled(); // 测试结束后恢复原方法,避免影响其他用例 reverseSpy.mockRestore(); });
3. 泛型指定类型的写法
也可以通过jest.spyOn的泛型参数明确类型,省去类型断言:
const reverseSpy = jest.spyOn<Array<any>, 'reverse'>(Array.prototype, 'reverse');
4. 关键注意点
- 不要监听
Array.reverse,reverse不是Array构造函数的静态方法,只有Array.prototype.reverse才是实际被调用的方法。 - 测试完成后调用
mockRestore()恢复原方法,避免污染其他测试用例的环境。
内容的提问来源于stack exchange,提问作者Xulvi
相关产品推荐
相关产品推荐

