配置ts-jest支持ESM模块(.mts测试文件)的错误排查与修复
解决ts-jest配置.mts测试文件的两类常见错误
一、Error [ERR_REQUIRE_ESM]: require() of ES Module... 错误分析与修复
原因
当package.json中设置"type": "module"时,Node.js默认将所有.ts/.js文件视为ES模块,但Jest加载.ts格式的配置文件(jest.config.ts)时,仍会尝试用CommonJS的require()机制加载,导致ES模块被错误地用CJS方式引入,触发该报错。此外,createJsWithTsEsmPreset生成的预设配置可能未完全适配你的NodeNext模块解析规则。
修复方案
- 改用
.mjs格式的配置文件(你已完成这一步),确保Jest以ES模块方式加载配置。 - 优化
jest.config.mjs的配置,确保和你的tsconfig.json(NodeNext模块解析、ESNext目标)完全适配:const jestConfig = { extensionsToTreatAsEsm: [".mts"], moduleFileExtensions: ["js", "mjs", "mts", "ts"], moduleNameMapper: { "^(\\.{1,2}/.*)\\.mjs$": "$1", "^(\\.{1,2}/.*)\\.ts$": "$1" }, roots: ["<rootDir>"], testMatch: [ "**/__tests__/**/*.+(mts|ts|js)", "**/?(*.)+(spec|test).+(mts|ts|js)", ], transform: { "^.+\\.(ts|mts)$": [ "ts-jest", { rootDir: ".", useESM: true, tsconfig: "./tsconfig.json" } ] }, preset: "ts-jest/presets/default-esm", testEnvironment: "node", }; export default jestConfig;
二、Matcher error: received value must be a mock or spy function 错误分析与修复
原因
使用jest.unstable_mockModule(ESM环境下的mock API)时,若仍用静态import导入被mock的模块,静态导入会在mock生效前加载原始模块,导致你断言的PubSub不是mock函数,而是原始的类/函数,触发匹配器错误。
修复方案
- 将静态导入改为动态导入,且必须在
jest.unstable_mockModule之后执行,确保mock先生效:// 先声明mock jest.unstable_mockModule("@google-cloud/pubsub", () => ({ __esModule: true, PubSub: jest.fn().mockImplementation(() => ({ topic: mockTopic, subscription: jest.fn().mockReturnValue({ on: mockSubscriptionOn, }), })), })); // 动态导入被mock的模块(必须在mock之后) const { PubSub } = await import("@google-cloud/pubsub"); // 若使用TypeScript,用jest.mocked包裹以获得正确的类型提示 const mockedPubSub = jest.mocked(PubSub); - 断言时使用动态导入得到的mock函数:
// 正确写法:用动态导入的mock函数 expect(mockedPubSub).toHaveBeenCalledTimes(1);
内容的提问来源于stack exchange,提问作者S Pears
相关产品推荐
相关产品推荐

