如何在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
相关产品推荐
相关产品推荐

