允许jest模拟从测试文件外部调用的函数的背后发生了什么



下面是一个关于如何模拟从测试文件外部调用的函数的示例。

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

最新更新