NodeJS 是否可以只为一个测试设置环境变量?

a9wyjsp7  于 2023-02-08  发布在  Node.js
关注(0)|答案(3)|浏览(134)

假设如下:

it('uses env variables correctly', function(done) {
    assert.equal(process.env.x * process.env.y, 10);
});

我想只为这个测试设置xy环境变量,可以吗?

kcugc4gi

kcugc4gi1#

以下是最常见的方法:

describe('env', function () {
  var env;

  // mocking an environment
  before(function () {
    env = process.env;
    process.env = { x: 2, y: 5 };
  });

  // running tests
  it('uses env variables correctly', function (done) {
    assert.equal(process.env.x * process.env.y, 10);
    done();
  });

  // restoring everything back
  after(function () {
    process.env = env;
  });
});
icnyk63a

icnyk63a2#

下面是一个非常常见的模式(由Leonid Beschastny回答)。

describe('env', function () {
  let envCache

  // mocking an environment
  before(() => {
    envCache = process.env;
  })

  // running tests
  it('reads env variables correctly', () => {
    process.env.x = 2
    process.env.y = 5

    assert.equal(process.env.x * process.env.y, 10)
  })

  // process.env is not just a plain object
  it('should convert undefined to a string', () => {
    process.env.UNDEF = undefined

    assert.equal(process.env.UNDEF, 'undefined')
  })

  // Trying to restore everything back
  after(() => {
    process.env = env
  })
})

但是这里有一个问题。process.env * 不是 * 普通对象,而您要用一个普通对象替换它。如果第二个测试是单独运行的,它将通过,因为这是process.env应该如何工作的。如果我们运行整个测试套件,* 第二个测试将失败 *!
这样设置测试会导致不同的行为,这是一件非常糟糕的事情。
相反,您应该使用delete来清除这些值,然后重新分配它们,如下所示:

describe('env', function () {
  let envCache

  // mocking an environment
  before(() => {
    envCache = process.env;
  })

  // running tests
  it('reads env variables correctly', () => {
    process.env.x = 2
    process.env.y = 5

    assert.equal(process.env.x * process.env.y, 10)
  })

  // process.env is not just a plain object
  it('should convert undefined to a string', () => {
    process.env.UNDEF = undefined

    assert.equal(process.env.UNDEF, 'undefined')
  })

  // Trying to restore everything back
  after(() => {
    Object.keys(process.env).forEach((key) => { delete process.env[key] })
    Object.entries(envCache).forEach(([ key, value ]) => {
      if (key !== undefined) {
        process.env[key] = value
      }
    })
  })
})

这将使行为更加一致,以防有人忘记您不应该将键process.env指定为未定义,而应该删除它们。

lsmepo6l

lsmepo6l3#

这个对我更有效。
在这种情况下,您不需要重新定义测试中可能需要的其他环境变量。

describe('fake env', () => {
  let envOrig;
  before(() => {
    envOrig = JSON.stringify(process.env);
    process.env.test = 'info';
  });

  after(() => {
    process.env = JSON.parse(envOrig);
  })

  it('check fake env', () => {
    expect(process.env.test).to.equal('info');
  })
});

describe('real env', () => {
  it('check real env', () => {
    expect(process.env.test).to.be.undefined;
  })
});

相关问题