0

我是 mocha/chai 的新手,我花了 2 天时间试图解决以下问题,但没有成功(请注意,下面的代码只是为了展示这个概念,它不是真正的代码)。

我有一个名为“api.js”的 JS 文件,其中通过 dotenv 框架在文件顶部初始化了一些变量,例如 SERVER_URL。

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”文件,其中:

测试.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 处理.env.SERVER_URL 值)?

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

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

专家,提前感谢您的宝贵帮助

4

3 回答 3

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
  })
})
于 2018-08-14T21:52:58.723 回答
0

您可以使用以下行使用 mocha 设置 .env 变量:

env SERVER_URL=htt://api.yourserver.com/ mocha test

这样 mocha 就知道您的 process.env.SERVER_URL 会发生什么

于 2018-08-14T21:53:55.483 回答
0

提高可测试性的一种方法是在可能process.env.SERVER_URL的情况下使用而不是SERVER_URL- 或getServerUrl()

const getServerUrl = () => process.env.SERVER_URL;

这种方式process.env.SERVER_URL可以在任何时候被嘲笑。

另一种方法是在被模拟后导入模块process.env.SERVER_URL。如果有多个测试使用此模块,这应该涉及 decaching,因为否则不会重新评估它。

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测试中没有,则可以在模拟后将其丢弃:

于 2018-08-14T22:05:38.590 回答