You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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';

之前配置无效的原因

  1. deps.moduleDirectories:该配置仅用于扩展模块查找目录,但custompackage不存在于node_modules时,Vitest仍会优先抛出模块未找到错误,无法直接通过目录映射生效。
  2. resolve.alias的entries写法:你之前使用的数组entries写法存在匹配优先级问题,直接采用键值对形式更稳定可靠。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:13:15