如果依赖项已加载,Sinon 存根不会改变行为

Gou*_*aul 0 unit-testing mocha.js node.js sinon

流程.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]);
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

流程.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);
      });
    });
  });
Run Code Online (Sandbox Code Playgroud)

在上面的场景中,存根可以工作,但会抛出模块未自行注册的错误。下面的场景存根不起作用。

流程.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);
          });
        });
      });
Run Code Online (Sandbox Code Playgroud)

"sinon": "9.0.2" "mocha": "^3.4.2", //甚至用 mocha 7.0.1 节点进行检查 --version v8.11.3 npm --v 6.2.0

and*_*gro 6

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

\n

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

\n

例如

\n

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

\n

完整示例:

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

注意:我在那里使用done,因为它是异步代码

\n
$ npx mocha process.test.js --exit\n\n\n  all count\n    \xe2\x9c\x93 getQueryCount\n\n\n  1 passing (17ms)\n\n$\n
Run Code Online (Sandbox Code Playgroud)\n