如何在node.js中存根process.env?

Mat*_*mat 68 stub node.js sinon

我想存根process.env.FOO使用bar.

var sinon = require('sinon');
var stub = sinon.stub(process.env, 'FOO', 'bar');
Run Code Online (Sandbox Code Playgroud)

我糊涂了.我看过文件,但我还是不明白.sinonjs docs

sinonjs是一个例子,不是sinonjs没关系.

Jos*_*ton 61

根据我的理解process.env,您可以在设置其属性时将其视为任何其他变量.但请记住,每个值都process.env必须是一个字符串.因此,如果您在测试中需要特定值:

   it('does something interesting', () => {
      process.env.NODE_ENV = 'test';
      // ...
   });
Run Code Online (Sandbox Code Playgroud)

要避免将状态泄漏到其他测试中,请确保将变量重置为其原始值或完全删除它:

   afterEach(() => {
       delete process.env.NODE_ENV;
   });
Run Code Online (Sandbox Code Playgroud)

  • 这个对我有用.要记住的一件事是,如果您在模块首次加载时测试读取NODE_ENV的模块,您可能需要设置NODE_ENV _before_加​​载模块(即可以在beforeEach块中设置NODE_ENV.)这看起来很明显,但它之前让我绊倒了. (8认同)
  • 这可行,但是我在使用`jest`时发现了一个怪癖。在生产代码中,我从env分配了一个const(例如const X = process.env.X`)。const是在(ES)模块作用域而不是函数作用域声明的。在重试测试中,我的测试总是通过`jest --watch`通过,但是在第一次运行中总是失败。这里有一个我不完全了解的订购问题。只要确保您始终在生产代码中(即在函数中)直接从`process.env`中读取,并且不在模块级对其进行缓存。 (2认同)

pll*_*lee 25

process.env通过克隆它并在拆卸它的拆卸方法中,我能够在单元测试中正确地进行存根.

使用Mocha的示例

const env = Object.assign({}, process.env);

after(() => {
    process.env = env;
});

...

it('my test', ()=> {
    process.env.NODE_ENV = 'blah'
})
Run Code Online (Sandbox Code Playgroud)

请记住,仅当您正在测试的函数中读取process.env时,此方法才有效.例如,如果您正在测试的代码读取变量并在闭包中使用它,则它将无法工作.您可能会使缓存的require无效以进行正确的测试.

例如,以下将没有env存根:

const nodeEnv = process.env.NODE_ENV;

const fnToTest = () => {
   nodeEnv ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这个过程大多有效.我不得不调整"后"方法.`after(()=> {process.env = Object.assign({},env);});`否则测试会操纵共享副本.需要在每次测试后设置一个新版本. (3认同)

小智 9

如果您想存根 process.env 中不存在的密钥,则可以使用此方法

const sinon = require('sinon')
let sandbox = sinon.createSandbox();
sandbox.stub(process, 'env').value({ 'SOME_KEY': 'SOME_VALUE' });
Run Code Online (Sandbox Code Playgroud)


Get*_*iax 6

使用 sinon,您可以像这样存根任何变量。

 const myObj = {
    example: 'oldValue', 
 };

 sinon.stub(myObj, 'example').value('newValue');

 myObj.example; // 'newValue'
Run Code Online (Sandbox Code Playgroud)

这个例子是表单 sinon 文档。https://sinonjs.org/releases/v6.1.5/stubs/


有了这些知识,您就可以存根任何环境变量。在您的情况下,它看起来像这样:

 let stub = sinon.stub(process.env, 'FOO').value('bar');
Run Code Online (Sandbox Code Playgroud)

  • 我收到错误“无法存根不存在的自有财产 FOO”。还使用 wallaby.js 来运行我的测试。 (5认同)

Hos*_*deh 6

如何在单元测试期间快速模拟 process.env。

https://glebbahmutov.com/blog/mocking-process-env/

const sinon = require('sinon')
let sandbox = sinon.createSandbox()

beforeEach(() => {
  sandbox.stub(process.env, 'USER').value('test-user')
})

it('has expected user', () => {
  assert(process.env.USER === 'test-user', 'wrong user')
})

afterEach(() => {
  sandbox.restore()
})
Run Code Online (Sandbox Code Playgroud)

但是在测试之前 process.env 中可能不存在的属性呢?您可以使用以下包,然后您将能够测试不存在的环境变量。

https://github.com/bahmutov/mocked-env