如何使用Sinon在Hapi / Lab测试中删除knex调用?

时间:2017-01-17 18:52:35

标签: sinon hapijs knex.js bookshelf.js lab

我正在尝试为新的Hapi应用设置测试模式。我过去使用过Mocha和Chai和Express,但我正在尝试使用Lab和Code来留在Hapi生态系统中。我也使用Bookshelf和Knex来处理数据库交互。

所以我有一个简单的健康终点我想测试。

'use strict';

const controller = require('../controller/healthController');

module.exports = [
  {
    method: 'GET',
    path: '/health',
    config: {
      handler: controller.health,
      description: 'The health endpoint returns 200',
      tags: ['api', 'health']
    }
  }
];

在处理程序中,它只是进行快速查询以确保它可以连接到数据库。

'use strict';

const bookshelf = require('../config/db');
const knex = bookshelf.knex;

module.exports = {
  health: function (request, reply) {
    knex.raw('SELECT version()').then(() => {
      reply('service is running');
    }).catch((err) => {
      reply({err: err, code: 500});
    });
  }
};

据我所知,需要服务器然后使用server.inject实际上并不启动服务器所以我不相信我应该有一个数据库连接,这意味着我应该嘲笑它db调用。对我来说奇怪的是,这个测试通过了:

'use strict';
const Code = require('code');
const Lab = require('lab');

const lab = exports.lab = Lab.script();
const describe = lab.describe;
const it = lab.test;
const expect = Code.expect;
const before = lab.before;

let server;

describe('health controller', () => {

  before((done) => {
    server = require('../../server');
    done();
  });

  it('health check replies 200 when successful call to db', (done) => {

    const options = {
      method: 'GET',
      url: '/health'
    };

    server.inject(options, (res) => {
      expect(res.payload).to.include('is running');
      expect(res.statusCode).to.equal(200);

      done();
    });

  });

});

所以我有两个问题。首先,我觉得上面的测试不应该真的通过。除非它正在加载所有内容并因此连接到db我想。也许我应该只测试控制器/处理程序方法?但我没有找到任何这方面的例子。

其次,我试图将knex.raw调用存根,当我尝试按下面这样做时,我得到500错误。

'use strict';
const Code = require('code');
const Lab = require('lab');
const Sinon = require('sinon');

const lab = exports.lab = Lab.script();
const describe = lab.describe;
const it = lab.test;
const expect = Code.expect;
const before = lab.before;

let server;
let knex = require('../../app/config/db').knex;

describe('health controller', () => {

  before((done) => {
    server = require('../../server');
    done();
  });

  it('health check replies 200 when successful call to db', (done) => {

    const stub = Sinon.stub(knex, 'raw').returns({});

    const options = {
      method: 'GET',
      url: '/health'
    };

    server.inject(options, (res) => {
      expect(res.payload).to.include('is running');
      expect(res.statusCode).to.equal(200);
      expect(stub.calledOnce).to.be.true();
      done();
    });

  });

});

我不确定为什么会这样。

2 个答案:

答案 0 :(得分:0)

server.inject完全就像您向真实服务器发出请求一样。因此,如果运行测试时数据库已启动,则端点将从数据库返回数据,就像手动启动服务器时一样。

Sinon.stub(knex, 'raw').returns({});无法工作。 knex.raw(…)应该返回一个Promise,而不是一个空对象。请尝试以下方法:

Sinon.stub(knex, 'raw').returns(Promise.resolve({}));

请注意:请务必在每次测试后致电server.stop(),以确保测试之间没有任何状态持续存在。一般来说,我认为您可以查看Hapi University repository中的示例测试文件。

答案 1 :(得分:0)

我认为Sinon.stub(knex, 'raw').resolves({});是更好的解决方案