如何使用sinon模拟一系列的knex调用

时间:2018-08-01 18:28:15

标签: mocha sinon knex.js

给出一个myknex.js:

export default { return require('knex')({client:'mysql',connection:{//conn}})}

我想为以下功能编写单元测试:

async function get({ userId }) {
  return await myknex('users')
    .where({ id: userId })
    .returning('*');
}

单元测试如下:

const sinon = require('sinon');
const sandbox = sinon.createSandbox();
const { myknex } = require('./myknex');

it('no record', async () => {
    sandbox
    .stub(myknex('users'), 'executeQuery').resolves([]);
    const result = await myrepo.get({ userId: 1 });
    const expectedResult = [];
    expect(result).to.deep.equal(expectedResult);
  });

我收到有关以下内容的错误消息:

TypeError: Cannot stub non-existent own property executeQuery

如何模拟链接的myknex调用?

1 个答案:

答案 0 :(得分:1)

由于您已经myknex.js导出了knex函数,因此我们需要使用proxyquire在测试文件中对其进行模拟。

const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const proxyquire = require('proxyquire'); // include proxyquire

const expectedResult = [];
const knexQuery = {
  where: sinon.stub().returnsThis(), // because we want to call `returning` afterwards
  returning: sinon.stub().resolves(expectedResult) // resolve it as promise
}
const myknexStub = sinon.stub().returns(knexQuery);
const myrepo = proxyquire('./src', { './myknex': myknexStub }); // your source file and stub myknex here

describe(('Test My Module'), () => {
  it('no record', async () => {
    const result = await myrepo.get({ userId: 1 });

    // many options to unit test the function    
    expect(myknexStub.calledWith('users')).to.be.ok;
    expect(knexQuery.where.calledWith({ id: 1 })).to.be.ok;
    expect(knexQuery.returning.calledWith('*')).to.be.ok;
    expect(knexQuery.returning.calledAfter(knexQuery.where)).to.be.ok;
    expect(result).to.deep.equal(expectedResult);
  });
});

希望有帮助