如何使用 Sinon 存根 "wrapper" 函数?

How to stub a "wrapper" function using Sinon?

我正在设置一个 Lambda 函数 (node.js),为了举例,我们将其保持在最低限度。

module.exports = (event, context, callback) {
  console.log("hello world")
}

但是,我创建了一个函数来包装 lambda 函数,它允许我在每个 Lambda 执行之前执行一些所需的函数(我有一组 Lambda 函数,这些函数使用它们的 Serverless Application Model (SAM)).它还允许我整合每个函数的一些日志记录和错误处理。

// hook.js
const connect = fn => (event, context, callback) => {
  someFunction()
    .then(() => fn(event, context, callback))
    .then(res => callback(null, res))
    .catch(error => {
      // logging
      callback(error)
    })
}

module.exports = { connect }

// index.js
const Hook = require("./hook")

exports.handler = Hook.connect((event, context, callback) => {
  console.log("hello world")
})

逻辑运行良好,Lambda 正在成功处理它。但是,我正在尝试使用 SinonJS 存根这个 Hook.connect 函数并且需要一些指导。

我只是想将它存根到 return 已解决的承诺,这样我们就可以继续处理每个 Lambda 函数 (fn(event, context, callback)) 中的代码。

const sinon = require("sinon")
const Hook = require("./hook")
const { handler } = require("./index")
const event = {} // for simplicity sake
const context = {} // for simplicity sake
const callback = {} // for simplicity sake

describe("Hello", () => {
  let connectStub

  beforeEach(() => {
    connectStub = sinon.stub(Hook, "connect").callsFake()

  afterEach(() => {
    connectStub.restore()
  })

  it("works", () => {
    const results = handler(event, context, callback)
    // assert
  })
})

我尝试了几种不同的方法,从基本的 sinon.stub(Hook, "connect") 到更复杂的方法,我尝试使用 [=20 在 hook.js 文件中存根私有函数=].

如有任何帮助,我们将不胜感激 -- 提前致谢。

这是一个工作测试:

const sinon = require('sinon');
const Hook = require('./hook');

const event = {}; // for simplicity sake
const context = {}; // for simplicity sake
const callback = {}; // for simplicity sake

describe('Hello', () => {

  let handler, connectStub;
  before(() => {
    connectStub = sinon.stub(Hook, 'connect');
    connectStub.callsFake(fn => (...args) => fn(...args));  // create the mock...
    delete require.cache[require.resolve('./index')];  // (in case it's already cached)
    handler = require('./index').handler;  // <= ...now require index.js
  });

  after(() => {
    connectStub.restore();  // restore Hook.connect
    delete require.cache[require.resolve('./index')];  // remove the modified index.js
  });

  it('works', () => {
    const results = handler(event, context, callback);  // it works!
    // assert
  });
});

详情

index.js 调用 Hook.connect 来创建其导出的 handler 一旦它运行 ,它运行 as一旦它是 required...

...因此 Hook.connect 的模拟需要在 之前 index.jsrequired:

Node.js caches modules,所以本次测试在之前也会清空Node.js缓存,保证index.js取到Hook.connect 模拟,并确保 index.js 和模拟 Hook.connect 从缓存中 删除 以防需要真正的 index.js稍后。