如何在Vitest测试用例中正确访问.env文件的环境变量?
Vitest 读取 .env 环境变量异常解决方案
process.env.JWT_SECRET_KEY取值为undefined不需要额外做特殊兼容,核心原因是环境变量加载时机不对或者配置方式有误,对应解决方法如下:
方案1:优先使用Vitest内置的env加载能力(推荐)
Vitest 从0.12.0版本开始内置了和Vite一致的.env文件自动加载能力,不需要手动引入dotenv包:
- 默认会自动加载项目根目录下的以下env文件,测试运行时默认mode为
test,加载优先级从低到高为:.env.env.local.env.test.env.test.local
- 所有加载到的变量会自动注入到
process.env中,测试代码里可以直接读取。 - 如果你的env文件不在项目根目录,或者需要自定义注入测试专用变量,可以直接在
vitest.config.ts中配置:
import { defineConfig } from 'vitest/config' export default defineConfig({ test: { // 指定env文件所在的目录 envDir: './your/env/dir/path', // 直接硬编码注入测试环境变量,优先级高于.env文件 env: { JWT_SECRET_KEY: 'your_test_jwt_secret' } } })
方案2:手动使用dotenv加载时调整执行时机
如果你坚持手动调用dotenv.config()加载,不要把这段逻辑写在beforeAll钩子中:
从Jest迁移时容易踩这个坑:Jest的模块执行时机和Vitest不同,放在
beforeAll里加载dotenv在Jest中可能正常运行,但Vitest基于Vite的模块预加载机制会更早执行顶层代码,必须把env加载逻辑放到顶层。
beforeAll是测试用例执行前的钩子,执行时机晚于测试文件顶层代码、依赖模块导入的执行时机。如果你的httpMocks.createRequest逻辑写在测试用例外层的顶层作用域,或者导入的依赖在加载时就读取了process.env的变量,等beforeAll里执行dotenv.config()时,相关变量已经被读取为undefined了。- 正确写法是把
dotenv.config()放在测试文件最顶部的顶层位置,在所有测试逻辑、非必要导入之前执行:
import dotenv from 'dotenv' // 顶层直接执行加载 dotenv.config() // 后续再写beforeAll、测试用例等逻辑 beforeAll(async () => { vi.clearAllMocks(); cleanUpMetadata(); controller = new UserController(container.get<UserServiceLocator>(Symbol.for("UserServiceLocator")), container.get<EmailServiceLocator>(Symbol.for("EmailServiceLocator"))); }); // 测试用例内的代码就可以正常读取process.env下的变量了 test('your test case', () => { let requestObj = httpMocks.createRequest({ cookies: { token: jwt.sign({ username: "testusername" }, process.env.JWT_SECRET_KEY!) } }); // 后续测试逻辑 })
额外排查点
如果以上配置完成后还是拿不到值,检查.env文件内的变量名是否拼写正确,变量值前后有没有多余的空格、注释,避免因为书写格式问题导致变量加载失败。
内容的提问来源于stack exchange,提问作者Bebet
相关产品推荐
相关产品推荐

