尝试了jest.fn, mock,spyOn三种方式都替换不了模块中调用的函数,究竟是哪里搞错了?
查了两天资料、issue最后总结有如题的三种方式可以部分替换模块中的某个函数,但死活就是没有效果,不知道问题到底是出在哪里了?有人用jest做过这种替换吗,请教
代码如下
// 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
模拟不起作用,是因为闭包的作用,B 中调用的并不是被模拟后的 A,而是实际的 A.
如果需要实现这种情况的模拟
一种方法是,修改源码如下
然后去模拟 A,这样当 B 去执行时就会找到 exports 下的 A.
第二种方法是,拆分
module.js
,将 A 拆分到另外一个文件a.js
文件,然后将 A 导入到module.js
中使用,这样直接去模拟a.js
也可以.第三种方法是,使用
Babel
插件,在编译的时候,添加一些额外的代码,实际上就是把需要手动去修改源码的过程,交给插件去自动完成了.这样的插件有:
这样可以在不用动源代码的情况下,完成需要的模拟功能.在我的
CodeSandbox
例子中,用的是babel-plugin-explicit-exports-references
CodeSandbox
更多详情 How to mock specific module function?