Search code examples
javascriptsinonknex.jsbookshelf.js

How to mock a callback function from bookshelf js using sinnon


I would like to mock this piece of code that is using bookshelf js (with knex) with sinon.

const campaigns = await models.Campaign.forge()
  .query((qb) => {
    qb.where("account_id", accountId);
    qb.andWhere("status", models.Campaign.STATUS.ACTIVE);
    qb.andWhere(
      "audience_create_trigger",
      models.Campaign.AUDIENCE_CREATE_TRIGGER.ON_ENTER
    );
  })
  .fetchAll();

How could I mock the inner queries inside the .query function. I am a bit lost

Thank you very much!


Solution

  • I finally solved the problem using Sinon. This code is covering almost all the behavior

    const assert = require("chai").assert
    const sinon = require("sinon")
    const models = require("../../../../models")
    
    
    const query = {
        query(func) {}
    }
    const qb = {
        where(arg1, arg2) {},
        andWhere(arg1, arg2) {}
    }
    const fetchAll = { async fetchAll() {} }
    
    const forgeStub = sinon.stub(models.Campaign, "forge").returns(query)
    const qbWhereStub = sinon
          .stub(qb, "where")
          .withArgs("account_id", accountId)
          .returns(null)
    const qbAndWhereStub = sinon.stub(qb, "andWhere").returns(null)
    const queryStub = sandbox
          .stub(query, "query")
          .callsArgWith(0, qb)
          .returns(fetchAll)
    const fetchAllStub = sandbox.stub(fetchAll, "fetchAll").returns(campaigs)
    
    //Calling the method
    
    //Verify
    assert.equal(qbWhereStub.callCount, 1)
    assert.equal(qbAndWhereStub.callCount, 2)
    assert.equal(forgeStub.callCount, 1)
    assert.equal(queryStub.callCount, 1)
    assert.equal(fetchAllStub.callCount, 1)
    assert.isTrue(qbWhereStub.getCall(0).calledWithExactly("account_id", accountId))
    assert.isTrue(qbAndWhereStub.getCall(0).calledWithExactly("status", models.Campaign.STATUS.ACTIVE))
    assert.isTrue(
      qbAndWhereStub
       .getCall(1)
       .calledWithExactly("audience_create_trigger", models.Campaign.AUDIENCE_CREATE_TRIGGER.ON_ENTER)
    )