如何在Vitest中Mock项目依赖外的自定义模块?
解决Vitest中Mock环境注入的
require('custompackage')问题 核心问题
JS包运行在已注入require('custompackage')的环境中,在Vitest中需要将该语句指向自定义mock,但Jest的moduleNameMapper配置无法直接迁移,尝试的deps配置、alias、vi.mock均未生效,同时import该模块也提示解析失败。
有效解决方案
方案1:通过resolve.alias直接映射模块
Vitest继承Vite的解析配置,通过resolve.alias可直接将模块名指向mock文件,同时兼容require和import调用:
// vitest.config.js import { defineConfig } from 'vitest/config'; import { resolve } from 'path'; export default defineConfig({ resolve: { alias: { // 精准匹配模块名,指向mock文件路径 'custompackage': resolve(__dirname, './tests/dependency-mocks/custompackage/index.js'), }, }, test: { // 可选:每次测试重置mock状态,避免跨测试污染 mockReset: true, }, });
方案2:正确使用vi.mock工厂函数
若不想修改全局配置,可在测试文件最顶部调用vi.mock,同时兼容ES模块和CommonJS导出(Vite会自动将require转换为import):
// 测试文件顶部,必须在导入被测试模块之前执行 vi.mock('custompackage', () => { const mockContent = { // 自定义mock方法/属性,示例: getConfig: vi.fn(() => ({ env: 'test' })), }; return { default: mockContent, // 兼容ES模块import __esModule: true, module.exports: mockContent, // 兼容CommonJS require }; }); // 之后再导入被测试模块 import { yourFunction } from '../src/hello.js';
之前配置无效的原因
deps.moduleDirectories:该配置仅用于扩展模块查找目录,但custompackage不存在于node_modules时,Vitest仍会优先抛出模块未找到错误,无法直接通过目录映射生效。resolve.alias的entries写法:你之前使用的数组entries写法存在匹配优先级问题,直接采用键值对形式更稳定可靠。vi.mock无效:大概率是调用时机晚于被测试模块的导入,或是未兼容CommonJS导出格式(原模块通过require调用,需在mock中设置module.exports)。
额外注意事项
若mock放在单独文件夹(如tests/dependency-mocks/custompackage),需确保该文件夹下的package.json正确配置main字段:
// tests/dependency-mocks/custompackage/package.json { "main": "index.js" }
内容的提问来源于stack exchange,提问作者Dave Stein
相关产品推荐
相关产品推荐

