You need to enable JavaScript to run this app. 如何使用Jest正确Mock ES6类?工厂参数配置jest.mock报方法不存在
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest正确Mock ES6类?工厂参数配置jest.mock报方法不存在

问题核心原因

你的错误写法踩了两个Jest Mock的典型规则误区:

  • jest.mock() 是纯副作用方法,没有任何返回值。它的作用是告诉Jest“测试运行时,遇到引入目标模块的地方,就用后面工厂返回的内容替换真实模块”,方法本身执行完返回undefined。你写的 const projectSettings = jest.mock(...) 拿到的永远是undefined,根本不是你在工厂函数里定义的构造函数,把undefined传进测试用例,自然调用getProjectDir会抛出方法不存在的错误。
  • 没有完成类的实例化逻辑:就算正确拿到了mock的构造函数,你也没有在测试用例里通过new生成实例,直接把构造函数本身传给被测方法,调用实例方法时也会触发报错。
符合规则的正确实现方式

1. 编写模块mock逻辑

在测试文件顶部写mock定义,注意不要接收jest.mock的返回值:

// 会被Jest自动提升到文件最顶部最先执行,替换./projectSettings的真实实现
jest.mock('./projectSettings', () => {
  // 提前构造带jest.fn()的实例对象
  const mockInstance = {
    getProjectDir: jest.fn(),
    setProjectDir: jest.fn()
  };
  // 返回mock类:调用new时直接返回上面定义的mock实例
  return jest.fn().mockImplementation(() => mockInstance);
});

2. 引入被mock的模块并实例化

正常import被mock的模块,手动实例化后拿到带mock方法的对象:

import ProjectSettings from './projectSettings';
// 实例化mock类,拿到的就是提前定义的带jest.fn()的对象
const projectSettings = new ProjectSettings();

3. 调整测试用例逻辑

把实例化好的mock对象传入被测方法,必要时给mock方法预设返回值,适配业务逻辑调用:

test('Set Project Directory Menu click should open dialog', async () => {
  // 给getProjectDir设置默认返回值,匹配业务里的调用逻辑
  projectSettings.getProjectDir.mockReturnValue('/default/test/path');

  const setDirMenuItem = subMenu.getSetProjectDirSubMenu(
    <any>mainWindow,
    <any>projectSettings
  );
  await setDirMenuItem.click();
  expect(dialog.showOpenDialog).toHaveBeenCalledTimes(1);
});

简化提示:如果./projectSettings是直接导出对象而非ES6类,可以去掉构造函数包裹,简化mock写法,不需要手动实例化:

jest.mock('./projectSettings', () => ({
  getProjectDir: jest.fn(),
  setProjectDir: jest.fn()
}));

这种写法下import拿到的直接就是带mock方法的对象,可以直接传入被测逻辑使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.13 14:15:10