我是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值)?
有没有任何重构的解决方案吗?
如果不是最好的解决方案是什么?
专家,在此先感谢您的宝贵帮助
答案 0 :(得分:0)
最简单的方法就是从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
})
})
答案 1 :(得分:0)
您可以使用以下代码在Mocha中设置.env变量:
env SERVER_URL=htt://api.yourserver.com/ mocha test
通过这种方式,摩卡咖啡会知道您的处理过程会带来什么。env.SERVER_URL
答案 2 :(得分:0)
一种提高可测试性的方法是在可能的情况下使用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
,可以在模拟后将其丢弃: