下面是一个关于如何模拟从测试文件外部调用的函数的示例。
math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => b - a;
export const multiply = (a, b) => a * b;
export const divide = (a, b) => b / a;
app.js
import * as math from './math.js';
export const doAdd = (a, b) => math.add(a, b);
export const doSubtract = (a, b) => math.subtract(a, b);
export const doMultiply = (a, b) => math.multiply(a, b);
export const doDivide = (a, b) => math.divide(a, b);
test.js
import * as app from "./app";
import * as math from "./math";
math.add = jest.fn();
math.subtract = jest.fn();
test("calls math.add", () => {
app.doAdd(1, 2);
expect(math.add).toHaveBeenCalledWith(1, 2);
});
test("calls math.subtract", () => {
app.doSubtract(1, 2);
expect(math.subtract).toHaveBeenCalledWith(1, 2);
});
jest(我猜还有其他测试库(在幕后做什么,允许它模拟在测试函数之外调用的函数?正如我所看到的,当测试文件导入app.js
时,测试文件无法控制该文件中使用的math
对象,但显然它可以控制。
请随意使用提供的示例之外的其他示例。我想从概念上解释一下这种魔法是如何运作的。请解释它是如何在JavaScript功能方面工作的,至少是类似JavaScript的伪代码。
谢谢!
Jest利用nodejs-vm功能,允许控制和修改代码执行https://nodejs.org/api/vm.html
这是在jest运行时包中完成的https://github.com/facebook/jest/blob/46c9c13811ca20a887e2826c03852f2ccdebda7a/packages/jest-runtime/src/index.ts#L531
您可以在本视频中看到描述jest架构的详细描述jest运行时&;节点vmhttps://youtu.be/3YDiloj8_d0?t=2251
要求拦截https://youtu.be/3YDiloj8_d0?t=2461