【问题标题】:Sinon stub out module's function from a middlewareSinon 从中间件中存根模块的功能
【发布时间】:2022-01-18 11:05:56
【问题描述】:

基于this question,我还需要对同样使用db-connection.js 文件的中间件进行测试。中间件文件如下所示:

const dbConnection = require('./db-connection.js')

module.exports = function (...args) {
   return async function (req, res, next) {
      // somethin' somethin' ...
      const dbClient = dbConnection.db
      const docs = await dbClient.collection('test').find()
 
      if (!docs) {
         return next(Boom.forbidden())
      }
   }
}

,数据库连接文件不变,即:

const MongoClient = require('mongodb').MongoClient
const dbName = 'test'
const url = process.env.MONGO_URL

const client = new MongoClient(url, { useNewUrlParser: true,
  useUnifiedTopology: true,
  bufferMaxEntries: 0 // dont buffer querys when not connected
})

const init = () => {
  return client.connect().then(() => {
    logger.info(`mongdb db:${dbName} connected`)

    const db = client.db(dbName)
  })
}

/**
 * @type {Connection}
 */
module.exports = {
  init,
  client,
  get db () {
    return client.db(dbName)
  }
}

中间件的工作原理是通过传递字符串列表(字符串是角色),我必须查询数据库并检查是否有每个角色的记录。如果记录存在,我将返回next(),如果记录不存在,我将返回next(Boom.forbidden())(下一个函数,来自 Boom 模块的 403 状态码)。

鉴于上面的细节,如果记录存在与否,如何进行测试以测试中间件的返回值?这意味着我必须准确地断言next()next(Boom.forbidden)

【问题讨论】:

    标签: javascript node.js unit-testing sinon node-mongodb-native


    【解决方案1】:

    基于answer。您可以为reqres 对象和next 函数创建存根。

    例如(不运行,但它应该可以工作。

    const sinon = require('sinon');
    
    describe('a', () => {
      afterEach(() => {
        sinon.restore();
      });
      it('should find some docs', async () => {
        process.env.MONGO_URL = 'mongodb://localhost:27017';
        const a = require('./a');
        const dbConnection = require('./db-connection.js');
    
        const dbStub = {
          collection: sinon.stub().returnsThis(),
          find: sinon.stub(),
        };
        sinon.stub(dbConnection, 'db').get(() => dbStub);
        const req = {};
        const res = {};
        const next = sinon.stub();
        const actual = await a()(req, res, next);
        sinon.assert.match(actual, true);
        sinon.assert.calledWithExactly(dbStub.collection, 'test');
        sinon.assert.calledOnce(dbStub.find);
        sinon.assert.calledOnce(next);
      });
    });
    

    【讨论】:

    • 试过类似的东西。确切地说,我在next函数上规划了sinon.spy,如果中间件返回next(),它就可以工作,但是当中间件返回next(Boom.forbidden)时它就不起作用。另外,为了检查不同的返回值,我还必须删除find 的返回值。
    • @felixbmmm 是的。我只给出一个测试用例。您可以使用sinon.stub().resolves().find() 方法提供不同的模拟数据。这样您就可以测试代码的每个分支
    猜你喜欢
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 2014-08-08
    • 2017-04-09
    • 1970-01-01
    • 2021-09-24
    • 2018-08-02
    • 2016-09-30
    相关资源
    最近更新 更多