nodejs/mocha/chai as promise : 在外部初始化的预期异步函数中使用的变量
nodejs/mocha/chai as promise : variables used in expected async function initialized outside
我是 mocha/chai 的新手,我花了 2 天时间尝试解决以下问题但没有成功(请注意,下面的代码只是为了展示概念,它不是真实的) .
我有一个名为"api.js"的JS文件,其中SERVER_URL等变量是通过dotenv框架在文件顶部初始化的。
api.js :
const SERVER_URL = process.env.SERVER_URL;
async function startAPI () {
return new Promise ( (resolve, reject) => {
console.log(`${SERVER_URL}`);
resolve();
});
exports = {startAPI};
现在我得到 "test.js" 文件,其中:
test.js:
require('../api');
it('the test', async () => {
return await expect(api.startAPI()).to.be.fulfilled;
});
问题是 SERVER_URL 在测试期间未定义,我无法修改 api.js (因为我不是所有者),只能修改 test.js.
我如何 运行 正确设置 SERVER_URL 变量的测试(api.js 的 process.env.SERVER_URL 值)?
有没有不重构的解决方案?
如果不是,最好的解决方案是什么?
专家,在此先感谢您的宝贵帮助
最简单的方法就是在您 运行 从 CLI 进行测试时设置这些变量:
例如在 npm 脚本中:
"scripts": {
"test": "SERVER_URL='http://example.com' mocha"
}
或直接从终端:
$ SERVER_URL='http://example.com' npm test
但更好的解决方案是在测试中模拟环境变量,几乎不需要重构。并且需要安装 proxyquire
。实际上这里不需要async/await
。
const proxyquire = require('proxyquire').noPreserveCache() // noPreserveCache is important to always have refreshed script with new process.env.SERVER_URL in each test
const MOCKED_SERVER_URL = 'http://example.com'
describe('example', () => {
let initialServerUrl
let api
beforeEach(() => {
initialServerUrl= process.env
})
afterEach(() => {
process.env = initialServerUrl
})
it('fulfilled', () => {
process.env.USE_OTHER_CODE_PATH = MOCKED_SERVER_URL
api = proxyquire('../api', {})
return expect(api.startAPI()).to.be.fulfilled
})
it('rejected', () => {
process.env.USE_OTHER_CODE_PATH = ''
api = proxyquire('../api', {})
return expect(api.startAPI()).to.be.rejected
})
})
您可以使用以下行使用 mocha 设置 .env 变量:
env SERVER_URL=htt://api.yourserver.com/ mocha test
这样 mocha 就知道您的 process.env.SERVER_URL
会得到什么
一种提高可测试性的方法是在可能的情况下使用 process.env.SERVER_URL
而不是 SERVER_URL
- 或者 getServerUrl()
:
const getServerUrl = () => process.env.SERVER_URL;
这样 process.env.SERVER_URL
可以在任何时候被嘲笑。
另一种方法是在 process.env.SERVER_URL
被模拟后导入模块。如果有不止一个测试使用这个模块,这应该涉及去缓存,否则它不会被重新评估。
const decache = require('decache');
...
let originalServerUrl;
beforeEach(() => {
originalServerUrl = process.env.SERVER_URL;
});
beforeEach(() => {
process.env.SERVER_URL = originalServerUrl;
});
it('the test', async () => {
decache('../api');
process.env.SERVER_URL = '...';
const api = require('../api');
await expect(api.startAPI()).to.be.fulfilled;
});
如果预计在测试中没有SERVER_URL
,可以在mock之后直接丢弃:
我是 mocha/chai 的新手,我花了 2 天时间尝试解决以下问题但没有成功(请注意,下面的代码只是为了展示概念,它不是真实的) .
我有一个名为"api.js"的JS文件,其中SERVER_URL等变量是通过dotenv框架在文件顶部初始化的。
api.js :
const SERVER_URL = process.env.SERVER_URL;
async function startAPI () {
return new Promise ( (resolve, reject) => {
console.log(`${SERVER_URL}`);
resolve();
});
exports = {startAPI};
现在我得到 "test.js" 文件,其中:
test.js:
require('../api');
it('the test', async () => {
return await expect(api.startAPI()).to.be.fulfilled;
});
问题是 SERVER_URL 在测试期间未定义,我无法修改 api.js (因为我不是所有者),只能修改 test.js.
我如何 运行 正确设置 SERVER_URL 变量的测试(api.js 的 process.env.SERVER_URL 值)?
有没有不重构的解决方案?
如果不是,最好的解决方案是什么?
专家,在此先感谢您的宝贵帮助
最简单的方法就是在您 运行 从 CLI 进行测试时设置这些变量:
例如在 npm 脚本中:
"scripts": {
"test": "SERVER_URL='http://example.com' mocha"
}
或直接从终端:
$ SERVER_URL='http://example.com' npm test
但更好的解决方案是在测试中模拟环境变量,几乎不需要重构。并且需要安装 proxyquire
。实际上这里不需要async/await
。
const proxyquire = require('proxyquire').noPreserveCache() // noPreserveCache is important to always have refreshed script with new process.env.SERVER_URL in each test
const MOCKED_SERVER_URL = 'http://example.com'
describe('example', () => {
let initialServerUrl
let api
beforeEach(() => {
initialServerUrl= process.env
})
afterEach(() => {
process.env = initialServerUrl
})
it('fulfilled', () => {
process.env.USE_OTHER_CODE_PATH = MOCKED_SERVER_URL
api = proxyquire('../api', {})
return expect(api.startAPI()).to.be.fulfilled
})
it('rejected', () => {
process.env.USE_OTHER_CODE_PATH = ''
api = proxyquire('../api', {})
return expect(api.startAPI()).to.be.rejected
})
})
您可以使用以下行使用 mocha 设置 .env 变量:
env SERVER_URL=htt://api.yourserver.com/ mocha test
这样 mocha 就知道您的 process.env.SERVER_URL
会得到什么一种提高可测试性的方法是在可能的情况下使用 process.env.SERVER_URL
而不是 SERVER_URL
- 或者 getServerUrl()
:
const getServerUrl = () => process.env.SERVER_URL;
这样 process.env.SERVER_URL
可以在任何时候被嘲笑。
另一种方法是在 process.env.SERVER_URL
被模拟后导入模块。如果有不止一个测试使用这个模块,这应该涉及去缓存,否则它不会被重新评估。
const decache = require('decache');
...
let originalServerUrl;
beforeEach(() => {
originalServerUrl = process.env.SERVER_URL;
});
beforeEach(() => {
process.env.SERVER_URL = originalServerUrl;
});
it('the test', async () => {
decache('../api');
process.env.SERVER_URL = '...';
const api = require('../api');
await expect(api.startAPI()).to.be.fulfilled;
});
如果预计在测试中没有SERVER_URL
,可以在mock之后直接丢弃: