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

如何在Jest中模拟函数依赖,使被调用函数生效?

解决Jest Mock函数a无法影响函数b调用的问题

问题核心:原模块中函数b调用的是内部定义的a函数,而非模块导出的a引用。你mock的只是模块对外导出的a,但b执行时根本没用到这个导出版本,所以mock不会生效。


方案一:修改原代码,让b依赖导出的a

这是最符合模块化规范的做法,让模块内部函数通过导出对象引用,测试时mock导出成员就能覆盖调用:

修改myFunctions.js:

// 方式1:直接引用exports对象
function a() {
    return 5;
}

function b() {
    return exports.a() + 5; // 使用导出的a
}

module.exports = { a, b };

或者更清晰地用统一导出对象:

// 方式2:提前定义导出对象
const functions = {
  a: () => 5,
  b: () => functions.a() + 5 // 引用同一对象内的a
};

module.exports = functions;

此时你的原测试代码就能正常工作,第二个测试会通过——因为b现在调用的是你mock后的导出版a。


方案二:在Jest Mock中重新定义b(无需修改原代码)

如果不想改动原代码,可以在jest.mock中重新实现b,让它绑定mock的a:

const { a, b } = require("./myFunctions");

jest.mock("./myFunctions", () => {
  const mockA = jest.fn(() => 10);
  return {
    a: mockA,
    b: () => mockA() + 5 // 手动让b依赖mock的a
  };
});

describe("myFunctions", () => {
  it("mocks a", () => {
    expect(a()).toEqual(10);
  });

  it("mock affects b", () => {
    expect(b()).toEqual(15);
  });
});

注意:这种方法需要在测试中同步维护b的实现,原代码修改后测试也要跟着调整,灵活性较差。


方案三:用jest.spyOn动态替换导出的a(配合原代码调整)

如果原代码已经改成让b依赖导出的a,也可以用spyOn动态mock并在测试后恢复:

const myFunctions = require("./myFunctions");

describe("myFunctions", () => {
  afterEach(() => {
    jest.restoreAllMocks(); // 测试结束后恢复原函数
  });

  it("mocks a and affects b", () => {
    jest.spyOn(myFunctions, "a").mockReturnValue(10);
    expect(myFunctions.b()).toEqual(15);
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:36:32