如何使用Vitest模拟$env/static/public环境变量?
用Vitest模拟$env/static/public环境变量的解决方案
以下是几种可行的实现方式,覆盖不同场景需求:
方法一:直接mock模块(推荐)
利用Vitest的vi.mock直接模拟$env/static/public模块,在测试前注入指定的环境变量值。由于ES模块的导入提升特性,需确保mock代码在目标模块导入前执行:
import { describe, it, expect, vi } from 'vitest'; // 先mock模块,确保在导入目标文件前生效 vi.mock('$env/static/public', () => ({ MY_VAR: 'true' })); describe('myVar 逻辑测试', () => { it('MY_VAR 为 "true" 时,myVar 返回 true', async () => { const { myVar } = await import('../src/lib/your-file'); // 替换为实际文件路径 expect(myVar).toBe(true); }); it('MY_VAR 为 "false" 时,myVar 返回 false', async () => { // 重新mock模块,覆盖之前的配置 vi.mock('$env/static/public', () => ({ MY_VAR: 'false' })); // 重新导入模块以应用新的mock值 const { myVar } = await import('../src/lib/your-file'); expect(myVar).toBe(false); }); });
方法二:通过环境变量动态控制
SvelteKit的$env/static/public变量对应前缀为PUBLIC_的系统环境变量,可通过动态读取process.env实现灵活切换:
import { describe, it, expect, vi } from 'vitest'; // mock模块,动态返回环境变量值 vi.mock('$env/static/public', () => ({ get MY_VAR() { return process.env.PUBLIC_MY_VAR || 'false'; } })); describe('myVar 逻辑测试', () => { it('PUBLIC_MY_VAR 为 "true" 时,myVar 返回 true', async () => { process.env.PUBLIC_MY_VAR = 'true'; const { myVar } = await import('../src/lib/your-file'); expect(myVar).toBe(true); }); it('PUBLIC_MY_VAR 为 "false" 时,myVar 返回 false', async () => { process.env.PUBLIC_MY_VAR = 'false'; const { myVar } = await import('../src/lib/your-file'); expect(myVar).toBe(false); }); // 测试后清理环境变量,避免影响其他测试 afterEach(() => { delete process.env.PUBLIC_MY_VAR; }); });
方法三:使用__mocks__文件夹配合别名
若需要复用mock逻辑,可创建专门的mock文件并通过Vitest配置别名指向:
1. 创建mock文件
在项目根目录创建__mocks__/env/static/public.ts:
// 初始默认值 export let MY_VAR = 'false'; // 提供修改变量的方法,供测试调用 export const setMY_VAR = (value: string) => { MY_VAR = value; };
2. 配置Vitest别名
修改vitest.config.ts,添加模块映射:
import { defineConfig } from 'vitest/config'; import { sveltekit } from '@sveltejs/kit/vite'; export default defineConfig({ plugins: [sveltekit()], test: { environment: 'jsdom', moduleNameMapper: { '^\\$env/static/public$': '<rootDir>/__mocks__/env/static/public.ts' } } });
3. 编写测试用例
import { describe, it, expect } from 'vitest'; import { setMY_VAR } from '$env/static/public'; describe('myVar 逻辑测试', () => { it('MY_VAR 为 "true" 时,myVar 返回 true', async () => { setMY_VAR('true'); const { myVar } = await import('../src/lib/your-file'); expect(myVar).toBe(true); }); it('MY_VAR 为 "false" 时,myVar 返回 false', async () => { setMY_VAR('false'); const { myVar } = await import('../src/lib/your-file'); expect(myVar).toBe(false); }); });
关键注意事项
- 由于
myVar是导出的常量,其值在模块导入时就已计算完成,因此每次修改环境变量后必须重新导入目标模块(使用await import()而非静态import)才能获取新值。 - 若使用SvelteKit,确保Vitest配置中启用了
sveltekit插件,避免模块解析错误。
内容的提问来源于stack exchange,提问作者Valentin Vignal
相关产品推荐
相关产品推荐

