尝试了jest.fn, mock,spyOn三种方式都替换不了模块中调用的函数,究竟是哪里搞错了?

发布于 2022-09-13 01:03:10 字数 1269 浏览 38 评论 0

查了两天资料、issue最后总结有如题的三种方式可以部分替换模块中的某个函数,但死活就是没有效果,不知道问题到底是出在哪里了?有人用jest做过这种替换吗,请教

demo链接

代码如下

// src/module.js

export const A = () => "function A";

export const B = () => A();
// test/mock.test.js

import * as Module from "../src/module";

it("jest.fn", () => {
  Module.A = jest.fn().mockReturnValue("mock function");
  const result = Module.toHaveBeenCalled();
  expect(Module.A).toHaveBeenCalled();
  expect(result).toEqual("mock function");
});

it("spyOn", () => {
  const spy = jest.spyOn(Module, "A").mockImplementation(() => "mock function");
  const result = Module.B();
  expect(spy).toHaveBeenCalled();
  expect(result).toEqual("mock function");
});

it("mock", () => {
  jest.mock("../src/module", () => {
    const original = jest.requireActual("../src/module");
    return {
      __esModule: true,
      ...original,
      A: jest.fn(() => "mock function")
    };
  });
  const module = require("../src/module");

  const result = module.B();
  expect(module.A).toHaveBeenCalled();
  expect(result).toEqual("mock function");
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

日裸衫吸 2022-09-20 01:03:10

模拟不起作用,是因为闭包的作用,B 中调用的并不是被模拟后的 A,而是实际的 A.

如果需要实现这种情况的模拟
一种方法是,修改源码如下

// src/module.js
export const A = () => 'function A'

export const B = () => exports.A()

然后去模拟 A,这样当 B 去执行时就会找到 exports 下的 A.

import * as Module from '../src/module'

it('spyOn', () => {
  const spy = jest.spyOn(Module, 'A').mockReturnValue('mock function')
  const result = Module.B()
  expect(spy).toHaveBeenCalled()
  expect(result).toEqual('mock function')
})

第二种方法是,拆分 module.js,将 A 拆分到另外一个文件 a.js 文件,然后将 A 导入到 module.js 中使用,这样直接去模拟 a.js 也可以.

第三种方法是,使用 Babel 插件,在编译的时候,添加一些额外的代码,实际上就是把需要手动去修改源码的过程,交给插件去自动完成了.
这样的插件有:

这样可以在不用动源代码的情况下,完成需要的模拟功能.在我的CodeSandbox例子中,用的是babel-plugin-explicit-exports-references

CodeSandbox

插件是否兼容项目,需要实际去测试才行.

另外建议可以配置 Babel 为只在测试环境中去使用插件.


更多详情 How to mock specific module function?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文