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

How to use sinon to mock a series of knex call

给定一个 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 调用?

因为你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);
  });
});

希望对您有所帮助