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

如何仅Mock模块中的单个函数?解决Jest中误Mock模块其他函数的问题

仅Mock模块中单个函数的Jest解决方案

这个问题我之前也碰到过,Jest默认如果用jest.mock直接覆盖模块导出的话,没明确指定的导出项会被替换成undefined,所以你调用init()时自然会出问题。下面给你两种靠谱的解决方案:

方案一:基于原始模块扩展Mock

这种方法会保留模块中其他导出的原始实现,只替换你需要Mock的函数:

修改你的foo.spec.ts代码如下:

import { bar, init } from './bar';
import { foo } from './foo';

// 导入原始模块,再扩展替换bar的实现
jest.mock('./bar', () => {
  // 获取模块的原始导出
  const originalModule = jest.requireActual('./bar');
  return {
    ...originalModule, // 保留所有原始导出
    bar: jest.fn(() => { console.log('in bar'); }) // 仅替换bar函数
  };
});

beforeAll(() => { 
  init(); // 这里调用的是原始的init函数
});

it('should return correct result', () => { 
  const result = foo(); 
  expect(bar).toHaveBeenCalled();
  // 其他断言逻辑
});

核心是用jest.requireActual获取模块的原始导出,再通过扩展运算符保留所有原始内容,最后只覆盖需要Mock的bar函数。

方案二:使用jest.spyOn替换单个函数

如果你不想Mock整个模块,只是临时替换某个函数的实现,jest.spyOn会更灵活:

修改后的foo.spec.ts代码:

import * as barModule from './bar';
import { foo } from './foo';

beforeAll(() => { 
  // 替换bar函数的实现
  jest.spyOn(barModule, 'bar').mockImplementation(() => { 
    console.log('in bar'); 
  });
  barModule.init(); // 调用原始init函数
});

// 测试结束后清理Mock,避免影响其他测试
afterAll(() => {
  jest.restoreAllMocks();
});

it('should return correct result', () => { 
  const result = foo(); 
  expect(barModule.bar).toHaveBeenCalled();
  // 其他断言逻辑
});

这种方式不需要提前Mock整个模块,而是在测试前动态替换bar函数的实现,测试完成后记得恢复Mock,保证测试的独立性。

两种方法都能解决你的问题,你可以根据自己的测试场景选择:如果需要整个测试文件中bar都被Mock,方案一更合适;如果只是在部分测试用例中替换,方案二更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 09:27:34