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

Vitest测试axios调用时未加载模拟环境变量问题排查

问题分析与解决方案

你的问题大概率是以下几个原因导致的,对应解决方案如下:

1. 模块导入顺序错误

如果在调用vi.stubEnv之前就导入了getData模块,模块加载时会直接读取真实的环境变量值,后续的stubEnv无法修改已加载模块中已经缓存的变量。

错误示例:

import { getData } from './getData';
import { vi, test, expect } from 'vitest';

test('测试getData', async () => {
  vi.stubEnv('VITE_KEY', 'test-key');
  vi.stubEnv('VITE_URL', 'test-url');
  const res = await getData();
  // 这里依然使用真实环境变量
});

解决方法:
将vi.stubEnv放在模块导入之前,或者使用动态导入确保环境变量模拟生效后再加载模块:

import { vi, test, expect } from 'vitest';

test('测试getData', async () => {
  vi.stubEnv('VITE_KEY', 'test-key');
  vi.stubEnv('VITE_URL', 'test-url');
  // 动态导入模块
  const { getData } = await import('./getData');
  const res = await getData();
  // 此时使用的是模拟的环境变量
});

2. Vite环境变量预编译导致硬编码

Vite在构建阶段会将import.meta.env中的变量直接替换为实际值,即使在测试环境,如果Vitest配置未禁用该特性,会导致变量被硬编码到代码中,vi.stubEnv无法覆盖。

解决方法:
在vitest.config.ts中启用环境变量模拟,避免预编译替换:

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    env: {
      mock: true, // 强制使用Vitest的环境变量模拟,跳过Vite的预替换
    },
  },
});

3. 函数内部缓存了环境变量值

如果getData函数提前将import.meta.env的变量赋值给了常量,后续请求会一直使用这个缓存的真实值,不会响应vi.stubEnv的修改。

错误示例:

// getData.ts
import axios from 'axios';

// 模块加载时就缓存了真实环境变量
const API_KEY = import.meta.env.VITE_KEY;
const BASE_URL = import.meta.env.VITE_URL;

export async function getData() {
  return axios.get(`${BASE_URL}/data`, {
    headers: { 'X-API-Key': API_KEY },
  });
}

解决方法:
每次请求时直接读取import.meta.env,或者将变量封装为动态获取的函数:

// 方案1:直接动态读取
export async function getData() {
  return axios.get(`${import.meta.env.VITE_URL}/data`, {
    headers: { 'X-API-Key': import.meta.env.VITE_KEY },
  });
}

// 方案2:封装为动态函数(适合需要复用的场景)
const getApiKey = () => import.meta.env.VITE_KEY;
const getBaseUrl = () => import.meta.env.VITE_URL;

export async function getData() {
  return axios.get(`${getBaseUrl()}/data`, {
    headers: { 'X-API-Key': getApiKey() },
  });
}

4. vi.stubEnv的作用域问题

如果vi.stubEnv是在describe或it块之外调用,但模块导入在更靠前的位置,同样会导致模块加载时读取真实变量。确保stubEnv在模块加载前执行,或者在beforeAll/beforeEach中调用并配合动态导入。

内容的提问来源于stack exchange,提问作者gespinha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:20:07