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]);
});
});
});
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 node --version v8.11.3 npm --v 6.2.0 检查
解决方案
为了使存根工作,您需要将process.js上的实现从使用解构赋值更改为正常赋值。
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 因为它是一个异步代码。
$ npx mocha process.test.js --exit
all count
✓ getQueryCount
1 passing (17ms)
$
推荐阅读
- java - 生成 Javadocs 以便在手机上轻松使用
- python - 如何迭代数据帧中的行并交换相邻的两个行并对交换后创建的新数据帧执行一些操作?
- excel - ActiveX 文本框显示上一个条目
- php - 从 DB 外观 en php laravel 获取数据
- ocaml - 在 OCaml 中查找最长的正整数
- php - 出于安全目的的 WordPress 版本更新
- ruby-on-rails - 为什么我在尝试部署博客时收到 HTTP 错误?
- java - mBluetoothGatt.getServices() 返回错误的 UUID
- python - 从具有列表元素的系列创建堆叠的熊猫系列
- html - 嵌套 div 的 z-index