如何使用node:test库模拟导入的函数?
解决node:test中模拟ES模块导入函数的问题
核心方案:用node:test内置Mock API拦截模块加载
node:test的Mock功能需要配合模块拦截逻辑,针对ES模块场景,关键要在模块加载前完成Mock配置,具体操作如下:
1. 启用实验性VM模块(必加)
ES模块的Mock依赖Node.js的VM模块特性,运行测试时必须带上--experimental-vm-modules参数:
node --experimental-vm-modules node:test your-test-file.js
2. 模拟单个导入函数
假设要Mock的模块是./utils.js,其中包含calculate函数,测试文件可按如下方式配置:
import { test, mock } from 'node:test'; import assert from 'node:assert'; // 拦截utils模块导入,替换calculate为Mock函数 mock('./utils.js', () => { return { calculate: mock.fn(() => 42) // 自定义Mock返回值 }; }); // 务必在Mock配置完成后导入目标模块 import { calculate } from './utils.js'; test('验证Mock的calculate函数', () => { const result = calculate(); assert.strictEqual(result, 42); assert.strictEqual(calculate.mock.callCount(), 1); });
3. 模拟ES6类(对标Jest类Mock)
如果要Mock ES6类,直接替换类的导出为Mock构造函数即可:
import { test, mock } from 'node:test'; import assert from 'node:assert'; mock('./User.js', () => { // 模拟User类,Mock其方法 const MockUser = mock.fn(() => { return { getName: mock.fn(() => 'Mocked Name') }; }); return { User: MockUser }; }); import { User } from './User.js'; test('验证Mock的User类', () => { const user = new User(); assert.strictEqual(user.getName(), 'Mocked Name'); assert.strictEqual(User.mock.callCount(), 1); assert.strictEqual(user.getName.mock.callCount(), 1); });
关于Loaders的使用
可以用自定义Loader实现全局模块Mock,但绝大多数场景下没必要——node:test内置的Mock API已经足够灵活。如果需要批量Mock第三方模块等复杂全局拦截,才考虑自定义Loader:
- 编写Loader文件(比如
mock-loader.js):
export async function resolve(specifier, context, defaultResolve) { if (specifier === 'axios') { // 将axios替换为本地Mock模块 return defaultResolve('./mocks/axios.js', context, defaultResolve); } return defaultResolve(specifier, context, defaultResolve); }
- 运行测试时指定Loader:
node --experimental-vm-modules --loader ./mock-loader.js node:test your-test-file.js
注意:自定义Loader会影响所有模块加载,灵活性不如node:test的局部Mock,优先用内置API。
常见坑点
- 导入顺序:必须先配置Mock,再导入被测试模块,否则原模块会提前加载导致Mock失效。
- 实验性参数:漏加
--experimental-vm-modules会直接报错,这是ES模块Mock的前提条件。 - 导出结构匹配:Mock的导出结构要和原模块完全一致,比如原模块是默认导出,Mock时要返回
default: ...。
内容的提问来源于stack exchange,提问作者Mascarpone
相关产品推荐
相关产品推荐

