nodejs / mocha / chai作为保证:在外部初始化的预期异步函数中使用的变量

时间:2018-08-14 21:25:32

标签: node.js promise async-await chai chai-as-promised

我是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值)?

有没有任何重构的解决方案吗?

如果不是最好的解决方案是什么?

专家,在此先感谢您的宝贵帮助

3 个答案:

答案 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,可以在模拟后将其丢弃: