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

使用jest.spyOn无法正确模拟默认导出函数的问题排查

Jest Spy无法Mock内部函数调用的问题解决

问题根源

你的测试用例失败的核心原因是:getUsers函数内部直接调用的是模块内定义的原始getJack函数,而不是你导出对象上的getJack方法。

当你用jest.spyOn(users, 'getJack')创建间谍时,只是修改了导出对象上的getJack引用,但模块内部的getJack变量依然指向原始函数,所以getUsers执行时还是会返回原始的'Jack',导致断言失败。

解决方案

这里提供三种可行的修改方式:

方案1:让内部函数引用导出对象上的方法

修改esm-user.js,让getUsers调用导出对象上的getJack:

// esm-user.js
const getJack = () => 'Jack';
const getJill = () => 'Jill';

const exports = {
  getJack,
  getJill,
  getUsers: () => [exports.getJack(), exports.getJill()]
};

export default exports;

这样getUsers会始终引用导出对象上的getJack,当Spy修改这个引用时,就能生效。

方案2:统一使用对象内的方法调用

把所有函数都挂载到同一个对象上,内部直接调用对象的方法:

// esm-user.js
const users = {
  getJack: () => 'Jack',
  getJill: () => 'Jill',
  getUsers: () => [users.getJack(), users.getJill()]
};

export default users;

这种写法更直观,getUsers直接调用users对象的getJack,Spy修改对象属性后会直接影响内部调用。

方案3:使用Jest模块Mock

在测试文件中通过jest.mock直接mock模块的导出,替换getJack的实现:

// esm-user-spy.spec.js
import users from './esm-user';

// 保留模块其他原始实现,仅mock getJack
jest.mock('./esm-user', () => {
  const original = jest.requireActual('./esm-user');
  return {
    ...original,
    getJack: jest.fn(() => 'Mock Jack')
  };
});

describe("Mocks and Spies", () => {
  test.only("partial mock (jack)", () => {
    expect(users.getUsers()).toEqual(['Mock Jack', 'Jill']);
  });
});

这种方式不需要修改源文件,直接在测试层替换模块导出的函数实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:18:13