如何在TypeScript中结合命名导出使用jest.requireActual()?
解决TypeScript中Jest Mock命名导出的问题
你的问题核心是Mock模块的导出结构和原模块不匹配:原functions.ts用的是命名导出(export const log),但你写的Mock用了默认导出(export default),导致被测试模块里import { log }找不到对应命名导出,最终log为undefined。
正确的Mock写法
修改__mocks__/functions.ts,让Mock和原模块保持一致的命名导出结构:
// 导入原模块的真实实现 const originalModule = jest.requireActual("./functions"); // 将log替换为无操作的Jest Mock函数 export const log = jest.fn(); // 导出原模块的其他所有函数(保留原有功能) export * from "./functions";
或者更直观的解构写法:
const originalModule = jest.requireActual("./functions"); // 提取原模块的log和其他成员,替换log为Mock export const { log: unusedOriginalLog, ...restOfFunctions } = originalModule; export const log = jest.fn(); export { ...restOfFunctions };
测试代码验证
你的测试代码无需改动(确保jest.mock("./src/backend/functions");的路径和functions.ts实际位置对应):
import { runMe } from "./stackoverflow"; jest.mock("./src/backend/functions"); test(`pass, but make sure it doesn't log error messages`, () => { runMe(); expect(true).toBeTruthy(); });
修改后,runMe()里的log会变成我们定义的无操作Mock函数,调用时不会输出任何内容,同时原functions.ts内的其他函数(如果有)会完全保留原有功能。
关键原理
Jest的模块Mock要求结构与原模块严格对齐:
- 原模块用命名导出,Mock必须对应使用命名导出;
jest.requireActual()用于导入原模块的真实实现,避免完全替换整个模块,只针对性修改需要Mock的部分;jest.fn()创建的无操作函数既能替代原log的输出行为,也支持后续通过Jest的Mock API做调用次数、参数等断言。
内容的提问来源于stack exchange,提问作者mikemaccana
相关产品推荐
相关产品推荐

