如何使用 sinnon 从 bookshelf js 模拟回调函数

How to mock a callback function from bookshelf js using sinnon

我想用 sinon 模拟这段使用 bookshelf js(带 knex)的代码。

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();

我如何模拟 .query 函数中的内部查询。 我有点迷茫

非常感谢!

终于用Sinon解决了这个问题。这段代码几乎涵盖了所有行为

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)
)

尝试使用 knex-mock-client 设置一个测试友好的 knex 实例。

测试看起来会简单得多。

import knex from "knex";
import { MockClient, getTracker } from "knex-mock-client";

describe("test", () => {
  let db;
  let tracker;

  beforeAll(() => {
    db = knex({ client: MockClient });
    tracker = getTracker();
  });

  afterEach(() => tracker.reset());

  it("should do something", () => {
    tracker.on
      .select(
        (query) =>
          query.sql.includes("table_name") && query.bindings.includes(accountId)
      )
      .responseOnce([]);

    // execute query using db;

    expect(tracker.history.select).toHaveLength(1);
  });
});