【问题标题】:Sinon stub is not changing the behavior if dependency is already loaded如果依赖项已经加载,Sinon 存根不会改变行为
【发布时间】:2020-07-02 12:53:52
【问题描述】:

process.js

const { getConnection, closeConnection } = require('./utils/db-connection.js');

const getQueryCount = query => new Promise((resolve, rejects) => {
  getConnection().then((conn) => {
    conn.query(query, (err, count) => {
      closeConnection(conn);
      if (err) {
        log.info(`Get Count Error:  ${err}`);
        return rejects(err);
      }
      return resolve(count[0][1]);
    });
  });
});

process.test.js

const dbConn = require('../src/utils/db-connection.js');
describe('all count', () => {
    beforeEach(() => {
      sinon.stub(dbConn, 'getConnection').resolves({ query: sinon.stub().yields(null, [[0, 5]]) });
      sinon.stub(dbConn, 'closeConnection');
  const process = require('./src/process'); //module is loaded after dependencies are stubbed

    });

    it('getQueryCount', () => {
      process.getQueryCount('query').then((result) => {
        expect(result).to.equal(5);
      });
    });
  });

在上述场景中,存根工作但抛出模块没有自注册。 并且下面的场景存根不起作用。

process.test.js

  const dbConn = require('../src/utils/db-connection.js');
      const process = require('./src/process'); // test file is loaded at the starting
    describe('all count', () => {
        beforeEach(() => {
          sinon.stub(dbConn, 'getConnection').resolves({ query: sinon.stub().yields(null, [[0, 5]]) });
          sinon.stub(dbConn, 'closeConnection');
    
        });
    
        it('getQueryCount', () => {
          process.getQueryCount('query').then((result) => {
            expect(result).to.equal(5);
          });
        });
      });

“sinon”:“9.0.2” "mocha": "^3.4.2", //甚至用 mocha 7.0.1 检查 节点--版本 v8.11.3 npm --v 6.2.0

【问题讨论】:

    标签: node.js unit-testing mocha.js sinon


    【解决方案1】:

    为了使存根工作,您需要将 process.js 上的实现从使用解构赋值更改为正常赋值 (reference)。

    const { getConnection, closeConnection } = require('./utils/db-connection.js');

    例如

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

    完整示例:

    // Simplified process.js
    const db = require('./db-connection.js');
    
    const getQueryCount = (query) => new Promise((resolve, rejects) => {
      // Called using db.getConnection.
      db.getConnection().then((conn) => {
        conn.query(query, (err, count) => {
          // Called using db.closeConnection.
          db.closeConnection(conn);
          if (err) {
            return rejects(err);
          }
          return resolve(count[0][1]);
        });
      });
    });
    
    module.exports = { getQueryCount };
    
    const sinon = require('sinon');
    const { expect } = require('chai');
    
    // Simple path just for example.
    const dbConn = require('./db-connection.js');
    const process = require('./process.js');
    
    describe('all count', function () {
      let stubGetConnection;
      let stubCloseConnection;
    
      beforeEach(function () {
        stubGetConnection = sinon.stub(dbConn, 'getConnection').resolves({ query: sinon.stub().yields(null, [[0, 5]]) });
        stubCloseConnection = sinon.stub(dbConn, 'closeConnection');
      });
    
      it('getQueryCount', function (done) {
        process.getQueryCount('query').then((result) => {
          expect(result).to.equal(5);
          // Need to verify whether stub get called once.
          expect(stubGetConnection.calledOnce).to.equal(true);
          expect(stubCloseConnection.calledOnce).to.equal(true);
          // Need to notify mocha when it is done.
          done();
        });
      });
    });
    

    注意:我使用 done there 因为它是一个asynchronous code

    $ npx mocha process.test.js --exit
    
    
      all count
        ✓ getQueryCount
    
    
      1 passing (17ms)
    
    $
    

    【讨论】:

    • 那行得通。谢了哥们。现在我在想,为什么我没有这样的想法。我浪费了将近 5 个周末
    猜你喜欢
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多