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

如何在Jest中针对依赖外部变量的if语句编写单元测试

问题:如何用Jest覆盖依赖process.env的JavaScript函数代码逻辑

我编写了如下JavaScript代码:

const authenticationTypeMapping = (payload) => {
  const { API_CONFIG } = process.env;

  try {
    const apiConfig = JSON.parse(API_CONFIG.toString('utf8'));
    // set authenticationType to Federated for production
    if (apiConfig.API_BASE_URL.includes('prd')) {
      payload.authenticationTypeName = 'Federated';
      // set authenticationType to Federated for dev or UAT
    } else if (apiConfig.API_BASE_URL.includes('dev') || apiConfig.API_BASE_URL.includes('uat')) {
      payload.authenticationTypeName = 'Basic';
    }
  } catch (err) {
    console.log(`Failed to map authenticationType. Unable to parse Secret: ${err}`);
  }
  return payload;
};

该函数依赖process.env中的API_CONFIG变量,根据API_BASE_URL的不同标识设置payload的authenticationTypeName。目前无法使用Jest覆盖try块内的代码逻辑,现有测试用例无法正确模拟该外部变量,请问需要添加什么内容才能完成单元测试覆盖?


解决方案

要覆盖该函数的所有代码分支,你需要在Jest测试中模拟process.env.API_CONFIG,并针对不同场景编写测试用例:

1. 模拟process.env变量的通用方法

在每个测试用例执行前,重置并设置process.env.API_CONFIG的值,注意要模拟成Buffer类型(因为原代码中调用了toString('utf8')):

// 在测试文件顶部或每个测试用例中重置环境变量
beforeEach(() => {
  jest.resetModules();
  process.env.API_CONFIG = Buffer.from(JSON.stringify({ API_BASE_URL: '' }));
});

afterEach(() => {
  delete process.env.API_CONFIG;
});

2. 覆盖生产环境分支(prd)

测试当API_BASE_URL包含prd时,authenticationTypeName被设置为Federated:

test('sets authenticationTypeName to Federated for production environment', () => {
  process.env.API_CONFIG = Buffer.from(JSON.stringify({ API_BASE_URL: 'https://api.prd.example.com' }));
  const payload = {};
  const result = authenticationTypeMapping(payload);
  expect(result.authenticationTypeName).toBe('Federated');
});

3. 覆盖开发/测试环境分支(dev/uat)

测试当API_BASE_URL包含dev或uat时,authenticationTypeName被设置为Basic:

test('sets authenticationTypeName to Basic for dev environment', () => {
  process.env.API_CONFIG = Buffer.from(JSON.stringify({ API_BASE_URL: 'https://api.dev.example.com' }));
  const payload = {};
  const result = authenticationTypeMapping(payload);
  expect(result.authenticationTypeName).toBe('Basic');
});

test('sets authenticationTypeName to Basic for UAT environment', () => {
  process.env.API_CONFIG = Buffer.from(JSON.stringify({ API_BASE_URL: 'https://api.uat.example.com' }));
  const payload = {};
  const result = authenticationTypeMapping(payload);
  expect(result.authenticationTypeName).toBe('Basic');
});

4. 覆盖catch块分支(解析失败场景)

测试当API_CONFIG无法被JSON解析时,函数进入catch块并返回原payload:

test('returns original payload when API_CONFIG parsing fails', () => {
  // 设置无效的JSON字符串
  process.env.API_CONFIG = Buffer.from('invalid json');
  const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
  const payload = { testKey: 'testValue' };
  const result = authenticationTypeMapping(payload);
  
  expect(result).toEqual(payload);
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Failed to map authenticationType'));
  
  consoleSpy.mockRestore();
});

5. 覆盖无匹配环境的分支

测试当API_BASE_URL不包含任何标识时,payload的authenticationTypeName不会被设置:

test('does not set authenticationTypeName for unknown environment', () => {
  process.env.API_CONFIG = Buffer.from(JSON.stringify({ API_BASE_URL: 'https://api.staging.example.com' }));
  const payload = {};
  const result = authenticationTypeMapping(payload);
  expect(result.authenticationTypeName).toBeUndefined();
});

内容的提问来源于stack exchange,提问作者R.Almoued

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:55:22