如何使用Sinon存根“包装器”函数?

时间:2019-04-05 19:52:18

标签: javascript node.js lambda 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函数进行存根,并且需要一些指导。

我只是想对它进行存根以便返回已解决的承诺,这样我们就可以继续处理每个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")到更复杂的方法,其中我尝试使用rewirehook.js文件内存入私有函数。

任何帮助将不胜感激-预先感谢您。

1 个答案:

答案 0 :(得分:2)

这是一个有效的测试:

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 ,一旦运行,它就会运行,{{1 }} ...

...因此,required的模拟必须在放置之前 Hook.connectindex.js

Node.js caches modules,因此此测试还将在测试之前之前清除Node.js缓存,以确保required选择index.js模拟,并以确保将带有模拟Hook.connect的{​​{1}}从缓存中删除 ,以防以后需要真正的index.js