如何使用sinnon模拟来自书架js的回调函数

时间:2019-12-17 16:50:53

标签: javascript sinon knex.js bookshelf.js

我想模拟这段使用书架js(带有knex)和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()

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

非常感谢您!

2 个答案:

答案 0 :(得分:0)

我终于使用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)
)

答案 1 :(得分:0)

尝试使用 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);
  });
});