我想使用bar
替换process.env.FOO
。
var sinon = require('sinon');
var stub = sinon.stub(process.env, 'FOO', 'bar');
我很困惑。我读了这份文件,但我还是不明白。sinonjs 文档
sinonjs 只是一个例子,不用非得使用 sinonjs。
我想使用bar
替换process.env.FOO
。
var sinon = require('sinon');
var stub = sinon.stub(process.env, 'FOO', 'bar');
我很困惑。我读了这份文件,但我还是不明白。sinonjs 文档
sinonjs 只是一个例子,不用非得使用 sinonjs。
根据我对process.env
的理解,当设置其属性时,您可以将其视为任何其他变量。但请记住,process.env
中的每个值都必须是字符串。因此,如果您需要测试中的特定值:
it('does something interesting', () => {
process.env.NODE_ENV = 'test';
// ...
});
afterEach(() => {
delete process.env.NODE_ENV;
});
jest
时发现了一个小问题。在我的生产代码中,我将env赋值给了一个常量(例如const X = process.env.X
)。该常量是在(ES)模块范围而不是函数范围内声明的。我的测试总是在jest --watch
上通过重试测试运行,但在第一次运行时总是失败。这里有一个我不完全理解的排序问题。请确保您始终直接从process.env
中读取您的生产代码(即在函数中),并且不要在模块级别缓存它。 - Jesse Buchananconst myValue = process.env.value ? process.env.value : 'default'
,如果您在测试中设置process.env.value,则无法正常工作。
然而,const myValue = () => (process.env.value ? process.env.value : 'default'
)可以按预期工作! - Rafael Marquesconst SWITCH_ON = (process.env.SWITCH_ON.toLowerCase() === 'true');
但它没有起作用,所以我将其改为两行:
var switchOn = process.env.SWITCH_ON; const SWITCH_ON = (switchOn === undefined ? false : switchOn.toLowerCase() === 'true');
最初的代码一直给我返回 undefined
的错误,而我正在执行 .toLowerCase()
操作。 - Scala Enthusiast我通过克隆 process.env
并在拆卸方法中恢复它,成功地将其正确地存根化,用于我的单元测试。
使用 Mocha 的示例
const env = Object.assign({}, process.env);
after(() => {
process.env = env;
});
...
it('my test', ()=> {
process.env.NODE_ENV = 'blah'
})
请记住,只有在您正在测试的函数中读取process.env时,此方法才有效。例如,如果您要测试的代码读取变量并在闭包中使用它,则此方法无效。您可能需要使require缓存失效以正确测试它。
例如下面的代码将不会使用env stubbed:
const nodeEnv = process.env.NODE_ENV;
const fnToTest = () => {
nodeEnv ...
}
after(() => { process.env = Object.assign({}, env); });
否则测试会操纵共享副本。每次测试都需要设置一个新版本。 - Kyle const myObj = {
example: 'oldValue',
};
sinon.stub(myObj, 'example').value('newValue');
myObj.example; // 'newValue'
这个例子来自Sinon文档。 https://sinonjs.org/releases/v6.1.5/stubs/
有了这个知识,你可以为任何环境变量设置存根。 在你的情况下,它应该是这样的:
let stub = sinon.stub(process.env, 'FOO').value('bar');
require('dotenv').config();
我意识到这通常会在我的应用程序运行时调用,但如果我直接运行我的单元测试,则会缺少此require语句。 - Von Pittman如果您想截取一个在process.env中不存在的键,可以使用这个方法。
const sinon = require('sinon')
let sandbox = sinon.createSandbox();
sandbox.stub(process, 'env').value({ 'SOME_KEY': 'SOME_VALUE' });
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()
})
那么对于在测试之前可能不存在于 process.env 中的属性怎么办呢?你可以使用以下软件包,然后就能够测试不存在的 env 变量了。
process.env.USER
没有值时,这个代码就行不通了。 - Sohail Si在一个类似于spec-helper.coffee
的文件中,你需要设置sinon沙盒,在此过程中要跟踪原始的process.env
并在每次测试后还原它,这样可以避免测试之间的泄漏,并且不必每次都记得重置。
_ = require 'lodash'
sinon = require 'sinon'
beforeEach ->
@originalProcessEnv = _.cloneDeep process.env
afterEach ->
process.env = _.cloneDeep @originalProcessEnv
process.env
。it 'does something based on an env var', ->
process.env.FOO = 'bar'
underscore
的 clone
函数可以替代 cloneDeep
,如果你已经在使用 underscore
而不是 lodash
,那么这个函数非常有用。 - Rob正如许多人指出的那样,如果在测试开始之前设置了环境变量,例如在您正在测试的文件中这样做,则 sinon 方法将无效。
const foo = process.env.YOUR_VAR;
Gleb Bahmutov编写了一个npm包,以一种不错的方式设置环境变量,无论您如何引用环境变量。
他的页面链接:https://glebbahmutov.com/blog/mocking-process-env/
npm包链接:https://github.com/bahmutov/mocked-env
它运行良好且非常容易实现。