使用 JEST 为单个测试更改 process.env 变量

Change process.env variable for single test using JEST

我正在尝试测试的文件中有以下代码:

foo.js

let localEnv = (process.env.LOCAL_ENVIRONMENT).toLowerCase() === 'prod' ? 'prod' : 'stage';

目前,我使用指向 env.jssetupFiles 设置此值,它包含:

process.env.LOCAL_ENVIRONMENT = 'prod';

我的问题是,如何在 foo.test.js 中将 process.env.LOCAL_ENVIRONMENT 更改为 test(或其他任何内容)?只需要在单个测试中执行此操作,所以这一行将包含在我的测试范围内。

我试过这样做,但没有成功...

foo.test.js

test('Nonprod', async () => { 
  process.env.LOCAL_ENVIRONMENT = 'test';
  ...
});

您可以根据自己的尝试更改该值。但是,您必须考虑到,在您的原始文件中,您仅在首次加载此脚本时访问该变量。为了完成这项工作,您必须这样做:

// in your test file foo.test.js
const prev = process.env.LOCAL_ENVIRONMENT
process.env.LOCAL_ENVIRONMENT = 'test'; // from now on the env var is test
const myModule = require('./foo.js'); // foo.js is executed and the var is read as test
process.env.LOCAL_ENVIRONMENT = prev; // change value back

这有一些问题,因为您不能用它测试多个场景(因为模块只加载一次)。

如果您想测试更多场景,您有多种选择:

一种是将逻辑和 process.env.LOCAL_ENVIRONMENT 分开,例如

function getLocalEnv(env = process.env.LOCAL_ENVIRONMENT) {
  return env.toLowerCase() === 'prod' ? 'prod' : 'stage';
}

这个函数现在很容易测试,不再依赖于环境变量

针对特定测试用例对其进行测试的最简单方法是将测试设置为描述范围,并根据您的需要在 beforeAll / afterAll 或 beforeEach / afterEach 挂钩中应用/删除 env 值。

describe('Test example', () => {
  describe('prod (default)', () => {
    test('do the thing', () => {
      doTheThing(); // process.env.LOCAL_ENVIRONMENT is by default 'prod' because of your setupFiles
    });
  });
  describe('test env', () => {
    const oldEnv = process.env.LOCAL_ENVIRONMENT; // or { ...process.env } to copy the whole env

    beforeAll(() => {
      process.env.LOCAL_ENVIRONMENT = 'test';
    });
    afterAll(() => {
      process.env.LOCAL_ENVIRONMENT = oldEnv; // do not forget to do this
    });

    test('do the thing', () => {
      doTheThing(); // process.env.LOCAL_ENVIRONMENT is 'test' here
    });
  });
});

我在这里找到了关于如何重置和 re-require 测试模块的答案: