JavaScript单元测试模拟环境变量的关键是隔离、临时、可恢复:Vitest推荐vi.stubEnv()自动恢复;Jest适用jest.mock()拦截配置模块;简单场景可用beforeEach/afterEach手动赋值清理,须避免顶层提前读取导致mock失效。

在 JavaScript 单元测试中模拟全局环境变量,关键不是“改掉”真实的 process.env,而是让被测代码读到你控制的值,且不影响其他测试。不同框架有不同推荐方式,核心逻辑一致:隔离、临时、可恢复。
用 Vitest 的 vi.stubEnv()(最推荐)
这是目前最安全、最语义清晰的方式,尤其适合 ESM 项目和并发测试:
-
vi.stubEnv('API_URL', 'https://test.api')—— 设置单个变量 -
vi.stubEnv({ NODE_ENV: 'test', DEBUG: 'true' })—— 批量设置 - 它会自动在每个测试结束后还原原始值,无需手动清理
- 即使测试中途抛错,也能保证环境干净
用 Jest 的模块级 mock(适合配置封装场景)
当环境变量读取逻辑被封装在独立配置文件(如 config.ts)中时,mock 整个模块更可靠:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 在测试文件顶部写
jest.mock('../src/config', () => ({ getApiUrl: () => process.env.API_URL || 'http://localhost' })) - 再在
beforeEach中设process.env.API_URL = 'https://mock.api' - 这样被测代码调用
getApiUrl()就会返回你设定的值,不碰真实process.env - 避免了顶层变量提前读取导致的 mock 失效问题
手动赋值 + 清理(仅限简单函数逻辑)
如果被测函数只是普通工具函数,且不依赖 Node 启动时就初始化的 env(比如没在模块顶层读 process.env),可用此法:
beforeEach(() => { process.env.MY_FLAG = 'on'; })afterEach(() => { delete process.env.MY_FLAG; })- 注意:绝不能在
describe外直接赋值,否则会污染整个测试套件 - TypeScript 下若报类型错误,可用
(process.env as any).MY_FLAG = 'on'或扩展NodeJS.ProcessEnv
绕不开的坑:顶层读取怎么办?
如果代码像这样写:
const DB_URL = process.env.DB_URL; // 模块加载时就执行<br>export function connect() { return new Client(DB_URL); }
那测试前改 process.env 已经晚了。此时必须:
- 用
vi.hoisted提前 stub(Vitest) - 或把配置提取成函数,延迟读取(重构建议)
- 或在测试中用
require.cache删除模块缓存后重新require(不推荐,难维护)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










