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

use*_*776 4 unit-testing jestjs

以下是有关如何模拟从测试文件外部调用的函数的示例。

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;
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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);
});
Run Code Online (Sandbox Code Playgroud)

jest(我猜还有其他测试库)在幕后做了什么,允许它模拟在测试函数之外调用的函数?正如我所见,当测试文件导入时,app.js测试文件无法控制math该文件中使用的对象,但显然它可以控制。

请随意使用除所提供的示例之外的另一个示例。我正在寻找这个魔法如何运作的概念性解释。请根据 JavaScript 功能和至少类似 JavaScript 的伪代码解释它是如何工作的。

谢谢你!

小智 6

Jest 利用 Nodejs 虚拟机功能,允许控制和修改代码执行 https://nodejs.org/api/vm.html

这是在 jest-runtime 包 https://github.com/facebook/jest/blob/46c9c13811ca20a887e2826c03852f2ccdebda7a/packages/jest-runtime/src/index.ts#L531中完成的

您可以在描述 jest 架构 jest-runtime && node vm 的视频中看到详细描述 https://youtu.be/3YDiloj8_d0?t=2251

需要拦截 https://youtu.be/3YDiloj8_d0?t=2461