使用 sinon 和 mocha 存根 pg-promise
Stubbing pg-promise using sinon and mocha
假设我有以下模块,如database.js
const initOptions = {}
const pgp = require('pg-promise')(initOptions)
const config = require('../../config')
const db = pgp({
host: config.database.host,
port: config.database.port,
database: config.database.database,
user: config.database.user,
password: config.database.password
})
module.exports = db
而下面的模块为create.js
const db = require('./database')
function create (name) {
return new Promise((resolve, reject) => {
db.func('create', name)
.then(data => {
return resolve(data)
})
.catch(err => {
return reject(err)
})
})
}
module.exports = create
我正在尝试 运行 对 create.js 进行单元测试,该单元测试将测试 db.func 是使用 'create' 作为第一个参数调用的,并且 'name'作为第二个,但实际上不需要建立数据库连接(因此测试可以 运行 离线)。
据我所知,这就是像 sinon.JS 这样的库的用途,所以我尝试创建一个测试并存根 db 对象。
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised)
const sinon = require('sinon')
const expect = chai.expect
const create = require('./create.js')
describe('Test Module', () => {
it('should test stuff', () => {
const db = require('./database')
const dbStub = sinon.stub(db, 'func').callsFake(Promise.resolve(null))
expect(create('test').then).to.be.a('Function')
})
})
然而,它失败了
TypeError: Cannot redefine property: func
很可能是因为我对 sinon 的接触有限...
我如何去存根(或者我可能需要模拟?)db 函数以便我可以测试它并确保 db.func 被调用?
您可以通过在 Initialization Options 中使用 no noLocking
选项禁用锁定来使属性可配置。这允许 sinon 替换属性:
const initOptions = { noLocking : true };
相关说明:
您的 create
函数正在创建一个不必要的承诺包装器,这是一个承诺反模式。您应该 return 来自 db.func
的结果,这已经是一个承诺:
function create(name) {
return db.func('create', name);
}
另外 callsFake
接受了一个函数,你给了它一个承诺。使用 returns
代替:
const dbStub = sinon.stub(db, 'func').returns(Promise.resolve(null))
I'm having trouble setting the noLocking
option. The docs state it can be set after initialization, however if I set it with db.$config.options.noLocking = true
, the same error occurs. However, if I set it in the database.js init options it works fine.
来自pg-promise的作者...
因为此时noLocking
只能影响任务和事务。由于协议的 db
级别仅启动一次,因此在库初始化后设置 noLocking
不会影响它。
我刚刚更新了 documentation 来澄清它:
This option is dynamic (can be set before or after initialization). However, changing it after the library's initialization will not affect Database objects that have already been created.
假设我有以下模块,如database.js
const initOptions = {}
const pgp = require('pg-promise')(initOptions)
const config = require('../../config')
const db = pgp({
host: config.database.host,
port: config.database.port,
database: config.database.database,
user: config.database.user,
password: config.database.password
})
module.exports = db
而下面的模块为create.js
const db = require('./database')
function create (name) {
return new Promise((resolve, reject) => {
db.func('create', name)
.then(data => {
return resolve(data)
})
.catch(err => {
return reject(err)
})
})
}
module.exports = create
我正在尝试 运行 对 create.js 进行单元测试,该单元测试将测试 db.func 是使用 'create' 作为第一个参数调用的,并且 'name'作为第二个,但实际上不需要建立数据库连接(因此测试可以 运行 离线)。
据我所知,这就是像 sinon.JS 这样的库的用途,所以我尝试创建一个测试并存根 db 对象。
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised)
const sinon = require('sinon')
const expect = chai.expect
const create = require('./create.js')
describe('Test Module', () => {
it('should test stuff', () => {
const db = require('./database')
const dbStub = sinon.stub(db, 'func').callsFake(Promise.resolve(null))
expect(create('test').then).to.be.a('Function')
})
})
然而,它失败了
TypeError: Cannot redefine property: func
很可能是因为我对 sinon 的接触有限...
我如何去存根(或者我可能需要模拟?)db 函数以便我可以测试它并确保 db.func 被调用?
您可以通过在 Initialization Options 中使用 no noLocking
选项禁用锁定来使属性可配置。这允许 sinon 替换属性:
const initOptions = { noLocking : true };
相关说明:
您的 create
函数正在创建一个不必要的承诺包装器,这是一个承诺反模式。您应该 return 来自 db.func
的结果,这已经是一个承诺:
function create(name) {
return db.func('create', name);
}
另外 callsFake
接受了一个函数,你给了它一个承诺。使用 returns
代替:
const dbStub = sinon.stub(db, 'func').returns(Promise.resolve(null))
I'm having trouble setting the
noLocking
option. The docs state it can be set after initialization, however if I set it withdb.$config.options.noLocking = true
, the same error occurs. However, if I set it in the database.js init options it works fine.
来自pg-promise的作者...
因为此时noLocking
只能影响任务和事务。由于协议的 db
级别仅启动一次,因此在库初始化后设置 noLocking
不会影响它。
我刚刚更新了 documentation 来澄清它:
This option is dynamic (can be set before or after initialization). However, changing it after the library's initialization will not affect Database objects that have already been created.