You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jest.mock在JS测试搭配TS模块时mock逻辑不生效问题

问题原因

核心诱因是模块加载顺序错误,和JS测试+TS源码的混合开发场景无关:

  • Jest的jest.mock调用默认会被提升(hoist)到文件顶部,但这个提升逻辑仅会优先于ES模块风格的import语句执行,不会提前到手动编写的CommonJSrequire调用之前。
  • 现有测试代码先执行了const { foo } = require('../src/foo/fooModule'),这行代码运行时会同步加载fooModule及其依赖的原始util模块,等后续执行jest.mock时,util模块已经完成加载,mock逻辑无法介入已经初始化的模块依赖树,自然不会执行传入的工厂函数。

如果调整顺序后仍不生效,可排查次要配置问题:TS配置中如果开启了baseUrl/paths路径别名,但Jest的moduleNameMapper没有同步对应规则,可能出现测试环境和源码环境解析到的util模块不是同一个文件的情况,但从当前给出的相对路径写法来看,该问题触发概率极低。

修复方案

二选一即可:

方案1:保留CommonJS语法,调整语句顺序

将jest.mock声明挪到所有require调用之前,保证mock逻辑在模块加载前完成注册:

// test/fooModule.test.js
// 先注册mock,再加载被测模块
jest.mock('../src/util', () => {
  return { utilFunction: () => 'mocked' };
});
const { foo } = require('../src/foo/fooModule')

describe('fooModule tests', () => {
  it('returns mocked util result', () => {
    expect(foo()).toBe('mocked');
  });
});

方案2:改用ES模块语法

用import语句加载被测模块,Jest会自动将jest.mock提升到所有import之前执行,无需手动调整顺序:

// test/fooModule.test.js
// 注意需确保babel/ts-jest配置支持ES模块解析
import { foo } from '../src/foo/fooModule'

jest.mock('../src/util', () => {
  return { utilFunction: () => 'mocked' };
});

describe('fooModule tests', () => {
  it('returns mocked util result', () => {
    expect(foo()).toBe('mocked');
  });
});
额外配置检查

如果上述修改后mock仍未生效,确认两项Jest配置:

  • moduleFileExtensions配置中包含ts、js后缀,可正确识别TypeScript源码文件
  • 若使用路径别名,moduleNameMapper规则和tsconfig.json中的paths配置完全一致,避免模块解析错位

内容的提问来源于stack exchange,提问作者mowwwalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:54:29