使用全局变量在Node.js

时间:2017-07-20 17:20:29

标签: javascript node.js testing mocha

我最近一直在测试在Node.js中开发的Web应用程序。我们正在使用Mocha,Sinon,Supertest和Proxyquire。

在我进入项目之前,另一个人开发了Web应用程序的测试套件。

在测试文件夹中,有一个名为commons.js的Javascript文件

commons.js

global.sinon = require('sinon');
global.expect = require('chai').expect;
global.supertest = require('supertest');
global.request = supertest('http://localhost:8051');
global.express = require('express');
global.app = express();
global.proxyquire = require('proxyquire');

这些变量用于所有测试。它们用于测试控制器和路由器。

我想知道这是否是一个很好的做法。一方面,我知道我们应该避免在我们的应用程序中使用全局变量,但我不知道这是否也适用于测试。另一方面,我觉得在每个测试文件的开头重复这些变量都会以某种方式违反DRY原则

我该怎么办?我应该重构所有测试还是只是保留原样?

1 个答案:

答案 0 :(得分:0)

正如评论中所述,这确实属于偏好领域。虽然不建议使用全局范围,因为它似乎是胶水,但沿着那条路走下去并不是什么大问题(特别是使用摩卡)。

但是,如果您的测试分布在多个文件中并且需要运行单个测试文件,则可能会遇到一个小缺陷。

<强>结构:

├── package.json
├── test.js
├── common.js
├── tests
    ├── test-1.js
    ├── test-2.js
    └── test-3.js

案例:运行单一(独立测试)

示例:让我们说运行所有测试大约需要30秒,您正在编写测试套件中的最后一个测试文件,该文件会进行独立测试。应该进行单一测试。

代码:

<强>的package.json

...
"scripts": {
  "mocha --reporter spec test.js"
},
...

common.js - 与上述相同

global.sinon = require('sinon');
global.expect = require('chai').expect;
global.supertest = require('supertest');
global.request = supertest('http://localhost:8051');
global.express = require('express');
global.app = express();
global.proxyquire = require('proxyquire');

<强> test.js

'use strict';

require('./common.js');

function runTest(testDesciption, file) {
  describe(testDesciption, function () {
    require('./tests/' + file);
  });
}

describe('My tests', function () {
    runTest('Running tests-1', 'test-1.js');
    runTest('Running tests-2', 'test-2.js');
    runTest('Running tests-3', 'test-3.js');
});

<强>测试/测试n.js

it("Should not throw error", function () {
    console.log(`Sinon: ${!!sinon}, Expect: ${!!expect}, Supertest ${!!supertest}, Proxyquire: ${!!proxyquire}`)
    expect(!!sinon).to.equal(true);
    expect(!!supertest).to.equal(true);
    expect(!!proxyquire).to.equal(true);
})

pitafall:     mocha --reporter spec tests/test-n.js

运行单个测试文件将导致ReferenceError,因为依赖项未包含在全局范围中。

解决方法

  • 错误:每个测试文件中都有require('../common.js')
  • 好:从代码中使用mocha --grep <describe_pattern>作为CLI OR describe.only

Mocha usage

Mocha exclusive tests

这样就避免了ReferenceError,因为测试将从根测试文件运行,加载common.js,跳过除提供的独占测试之外的所有测试。

每个测试文件中的依赖关系声明的案例

我认为在每个文件中声明依赖关系是一种很好的做法。

1。揭秘require()

  

模块在第一次加载后进行缓存。这意味着(除其他外)每次调用require(&#39; foo&#39;)将获得完全相同的返回对象,如果它将解析为同一文件。

在第一次要求之后,要求模块不会减慢你的速度。

<强> 2 即可。每个文件都是一个紧凑的逻辑单元,包含作为独立测试运行所需的所有内容。

3。:某些测试文件需要您正在使用的软件包的子集(并非全部),保持其清洁。

TL; DR:总而言之,如果适合您,则无需更改内容。希望这些信息能为您的决策提供更多背景信息。