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

Jest模块内函数Mock失效:testBar未使用Mock的testBar1

解决Jest模块内函数相互调用时Mock失效的问题

问题原因

你遇到的问题核心在于:模块内部的函数调用是直接引用本地定义的函数,而非通过模块的导出对象。你用jest.mock替换了模块导出的testBar1,但testBar里调用的是模块内直接定义的原始testBar1,根本没用到你Mock的导出版本,所以Mock不生效。

解决方案

方案一:修改模块内部引用方式,通过导出对象调用函数

调整Tools.ts的代码,让testBar通过模块的导出对象来调用testBar1,这样就能让Mock的导出版本生效:

// Tools.ts
export const testBar1 = () => {
  return 'original test2';
};

export const testBar = () => {
  // 改为通过exports调用testBar1
  return 'test' + exports.testBar1();
};

或者使用模块自身的导入引用(适配ES模块规范):

// Tools.ts
import * as self from './Tools';

export const testBar1 = () => {
  return 'original test2';
};

export const testBar = () => {
  return 'test' + self.testBar1();
};

此时你原来的测试代码就能正常工作,Mock的testBar1会被testBar调用。

方案二:使用jest.spyOn动态Mock导出函数

不需要修改原模块代码的前提下,用jest.spyOn来Mock模块导出的testBar1,同时确保测试时调用的是模块导出的testBar(避免解构导入导致的引用快照问题):

// Tools.test.ts
import * as Tools from './Tools';

test('should mock functions correctly', () => {
  // SpyOn并Mock返回值
  const mockTestBar1 = jest.spyOn(Tools, 'testBar1').mockReturnValue('mocked test2');
  
  // 调用模块导出的testBar
  const result = Tools.testBar();
  
  expect(result).toBe('testmocked test2');
  
  // 测试完成后恢复原始函数
  mockTestBar1.mockRestore();
});

注意:这种方法需要配合方案一的模块内部引用修改,否则testBar还是会调用本地原始的testBar1。

方案三:重构代码,拆分模块(推荐长期方案)

把testBar1抽离到单独的子模块,降低模块内耦合度,这样Mock会更直观,也符合单一职责原则:

// utils.ts
export const testBar1 = () => {
  return 'original test2';
};
// Tools.ts
import { testBar1 } from './utils';

export const testBar = () => {
  return 'test' + testBar1();
};

测试时直接Mockutils模块的testBar1即可:

// Tools.test.ts
import { testBar } from './Tools';

jest.mock('./utils', () => ({
  testBar1: jest.fn(() => 'mocked test2')
}));

test('should mock functions correctly', () => {
  const result = testBar();
  expect(result).toBe('testmocked test2');
});

这种方式不需要修改原函数的调用逻辑,模块职责更清晰,Mock也更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:57:14