如何在Jest中spyOn同一模块内的函数?解决Mock失效问题
问题根源
函数A内部直接调用的是模块内定义的本地函数B,而非导出对象中的B属性。你用jest.spyOn(index, 'B')mock的是导出对象上的B,但A持有本地B的引用,所以mock不会生效。
解决方案(尽量不改动原代码)
方案一:使用rewire库修改模块内部函数
rewire可以直接修改模块内部的私有变量/函数,无需改动业务代码:
- 安装依赖:
npm install rewire --save-dev
- 修改测试文件:
const rewire = require('rewire'); const indexModule = rewire('../index.ts'); describe('Test suit', () => { it('should test function A correctly', async () => { // 创建mock函数,指定返回值为true const mockB = jest.fn().mockResolvedValue(true); // 替换模块内部的B函数 indexModule.__set__('B', mockB); // 获取导出的A函数(此时A内部会调用mock后的B) const { A } = indexModule; const result = await A('a', 'b', 'c'); // 执行断言 expect(mockB).toHaveBeenCalled(); // 根据业务逻辑添加其他断言 }); });
方案二:极小改动原代码(可选)
如果允许对index.ts做最小修改,让A通过导出对象调用B,即可直接用jest.spyOn生效:
修改index.ts中的A函数:
async function A (a:string, b:string, c:string) { // code await exports.B(data); // 改为调用导出对象上的B // code }
对应的测试代码可保持你原来的写法,此时jest.spyOn(index, 'B')会正确mock调用。
内容的提问来源于stack exchange,提问作者Piyush Raut
相关产品推荐
相关产品推荐

