如何模拟我的配置文件进行测试?

Hal*_*ton 5 javascript tdd unit-testing node.js koa

我有一个我刚刚开始的Koa应用程序,我需要测试一些从配置文件中获取数据的东西.

我需要使用特定数据进行测试,但我不确定如何修改测试从配置文件中接收的数据.

例:

app.js

var router = require('koa-router');
var config = require('./config.js');
var db     = require('./db.js');
var auth   = require('./auth');
var app    = require('koa')();

router.get('/', function *() {
  if(auth(this.req, config.credentials.secret)) { // Authenticates request based on a hash created using a shared secret
    this.body = "Request has been authenticated";
  }
});

app.use(router.routes());
app = module.exports = http.createServer(app.callback());

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)

appSpec.js

var request = require('supertest');
var app = require('../app.js');

describe('app', function() {
  it('should authenticate all requests against config shared secret', function() {
    var secret    = 'some_secret';
    var validHash = /* hash created from test secret and query */;

    request(app)
      .get('/')
      .query({query: 'some_query'})
      .query({hash: validHash})
      .expect(403, done);

  });
});
Run Code Online (Sandbox Code Playgroud)

此规范将失败,因为应用程序将使用配置文件中的秘密(空字符串)而不是我的测试秘密.

Hal*_*ton 6

好吧,我用一些不同的方法来处理这个问题.

对于我的特定用例,我找到的最佳选择是proxyquire.它是一个npm包,允许您覆盖测试套件中所需的任何文件中的依赖项.

所以,如果我正在测试这个模块:

./controllers/myController.js

var config = require('../config.js');

module.exports = function() {
 // Do some stuff
};
Run Code Online (Sandbox Code Playgroud)

我会做这样的事情:

./test/controllers/myControllerSpec.js

var proxyquire = require('proxyquire');
var config = {
  credentials: {
    secret: 'my_secret'
  }
  // other fake config stuff
};
var myController = proxyquire('../../controllers/myController.js', {'../config.js', config});

describe('myController', function() {
  // TESTS
});
Run Code Online (Sandbox Code Playgroud)

这个实例myController将使用我的测试配置.

这不适用于端到端测试,除非您导入配置的唯一位置是主应用程序文件.


pet*_*teb 5

我将node-config用于我的配置文件,并基于计算机或env变量加载配置。

您可以使用多种格式(.json,.js,yaml等)指定配置。使用默认设置,您需要config在应用根目录中创建一个文件夹,并default.<format>使用默认配置创建一个。

要覆盖它进行测试,可以test.<format>config目录中创建一个文件。设置时NODE_ENV=testnode-config将看到加载默认配置文件,然后加载测试配置文件,如果值存在任何冲突,则测试配置文件将覆盖默认文件中的值。

下面是设置了完整的文档配置文件node-config

下面是一个使用的例子node-config.js配置文件格式。

./config/default.js

module.exports = {
  credentials: {
    secret: ''
  }
}
Run Code Online (Sandbox Code Playgroud)

./config/test.js

module.exports = {
  credentials: {
    secret: 'abcdef123456'
  }
}
Run Code Online (Sandbox Code Playgroud)

app.js

var router = require('koa-router');
var config = require('config');
var db     = require('./db.js');
var auth   = require('./auth');
var app    = require('koa')();

var credentials = config.get('credentials');

router.get('/', function *() {
  if(auth(this.req, credentials.secret)) { // Authenticates request based on a hash created using a shared secret
    this.body = "Request has been authenticated";
  }
});

app.use(router.routes());
app = module.exports = http.createServer(app.callback());

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)

  • 当您想使用不同的秘密值进行测试时该怎么办?例如,当 Secret 为空时编写测试? (2认同)

Hol*_*ins 5

Jest 对这个案例有很好的支持。在您的测试文件中,添加

jest.mock('../config.js', () => ({ 
  credentials: {
    secret: 'my_secret'
  }
  // other fake config stuff }));
Run Code Online (Sandbox Code Playgroud)