【问题标题】:Sinon stub out module's functionSinon stub out 模块的功能
【发布时间】:2022-01-18 10:34:08
【问题描述】:

假设我在这里有一个文件:

// a.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())
      }
   }
}

db-connection.js 看起来像这样:

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

并且我有一个测试来存根 find() 方法以至少返回 true(为了测试 a.js 的返回值是否为 true。我该怎么做?

【问题讨论】:

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


    【解决方案1】:

    单元测试策略是对 DB 连接进行 stub,我们不需要连接真正的 mongo DB 服务器。这样我们就可以在与外部环境隔离的环境中运行测试用例。

    您可以使用stub.get(getterFn) 替换dbConnection.db getter 的新getter。

    由于 MongoDB 客户端初始化发生在您需要 db-connection 模块时。在需要 adb-connection 模块之前,您应该从环境变量中为 MongoClient 提供正确的 URL。否则 MongoDB nodejs 驱动会抛出无效 url 错误。

    例如

    a.js:

    const dbConnection = require('./db-connection.js');
    
    module.exports = function () {
      const dbClient = dbConnection.db;
      const docs = dbClient.collection('test').find();
    
      if (!docs) {
        return true;
      }
    };
    

    db-connection.js:

    const MongoClient = require('mongodb').MongoClient;
    const dbName = 'test';
    const url = process.env.MONGO_URL;
    
    const client = new MongoClient(url, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    
    const init = () => {
      return client.connect().then(() => {
        console.info(`mongdb db:${dbName} connected`);
        const db = client.db(dbName);
      });
    };
    
    module.exports = {
      init,
      client,
      get db() {
        return client.db(dbName);
      },
    };
    

    a.test.js:

    const sinon = require('sinon');
    
    describe('a', () => {
      afterEach(() => {
        sinon.restore();
      });
      it('should find some docs', () => {
        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 actual = a();
        sinon.assert.match(actual, true);
        sinon.assert.calledWithExactly(dbStub.collection, 'test');
        sinon.assert.calledOnce(dbStub.find);
      });
    });
    

    测试结果:

      a
        ✓ should find some docs (776ms)
    
    
      1 passing (779ms)
    
    ------------------|---------|----------|---------|---------|-------------------
    File              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ------------------|---------|----------|---------|---------|-------------------
    All files         |      75 |       50 |      25 |      75 |                   
     a.js             |     100 |       50 |     100 |     100 | 7                 
     db-connection.js |      60 |      100 |       0 |      60 | 11-13,21          
    ------------------|---------|----------|---------|---------|-------------------
    

    【讨论】:

    • 我已经添加了我的db-connection.js 文件。根据您的回答,我认为我无法再次注册 db 对象。另外,findcollection 方法来自模块的函数。
    • @felixbmmm 更新答案。
    • 很好的解释!但是如果返回类型是一个函数呢?我会更新我的问题,因为我采取了不同的方法来解决我的内部问题。
    • @felixbmmm 如果您有新问题,请提出新问题
    • 我已经在这里stackoverflow.com/questions/70749783/… 发布了这个问题。谢谢你的回答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2015-08-21
    • 2019-04-03
    • 1970-01-01
    • 2021-08-06
    相关资源
    最近更新 更多