如何使用Jest模拟同文件中被调用的函数?
Jest 模拟同文件内函数调用的两种方案
一、用 jest.spyOn(推荐)
因为funcA、funcB和importantFunc在同一个文件里,你可以通过模块导出的方式监听importantFunc,替换它的实现逻辑。
举个例子,你的业务代码文件(比如utils.js):
export const importantFunc = () => { return '真实执行的结果'; }; export const funcA = () => { // 直接调用同文件的importantFunc return importantFunc(); }; export const funcB = () => { return importantFunc(); };
测试文件里这么写:
import * as utils from './utils'; test('测试funcA:模拟importantFunc的返回值', () => { // 监听utils模块里的importantFunc,替换成自定义模拟函数 const mockImportant = jest.spyOn(utils, 'importantFunc').mockReturnValue('我是模拟结果'); const result = utils.funcA(); // 验证结果是否符合预期 expect(result).toBe('我是模拟结果'); // 验证importantFunc是否被调用了 expect(mockImportant).toHaveBeenCalled(); // 测试结束后恢复原函数,避免影响其他测试用例 mockImportant.mockRestore(); });
二、直接用 jest.fn 覆盖模块导出
如果不想用spyOn,也可以直接替换模块导出的importantFunc:
import * as utils from './utils'; test('测试funcB:用jest.fn模拟', () => { // 先保存原函数,方便后续恢复 const originalFunc = utils.importantFunc; // 替换成jest创建的模拟函数,指定返回值 utils.importantFunc = jest.fn().mockReturnValue('模拟的返回内容'); const result = utils.funcB(); expect(result).toBe('模拟的返回内容'); expect(utils.importantFunc).toHaveBeenCalledTimes(1); // 恢复原函数 utils.importantFunc = originalFunc; });
关键注意事项
- 如果你的业务代码里是直接调用函数名(比如
importantFunc()),而不是通过模块导出引用,那上面的方法不生效。这种情况需要调整代码结构,比如把所有函数挂在一个对象上导出,或者用import { importantFunc } from './utils'的方式在同文件内引用(看起来冗余,但方便测试)。 - 不管用哪种方法,测试后一定要恢复原函数,不然会导致其他测试用例拿到被修改后的函数,出现错误。
jest.spyOn的mockRestore()方法会自动帮你恢复,比手动保存原函数更省心。
内容的提问来源于stack exchange,提问作者Farhan
相关产品推荐
相关产品推荐

