假设我有一个以下模块,如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?
答案 0 :(得分:3)
您可以通过在.Net fiddle中使用no noLocking
选项禁用锁定来配置属性。这允许sinon替换属性:
const initOptions = { noLocking : true };
在相关说明中:
你的create
函数正在创建一个不必要的promise包装器,这是一个promise反模式。您应该只返回db.func
的结果,这是一个承诺:
function create(name) {
return db.func('create', name);
}
同样callsFake
需要一个函数,你正在给它一个承诺。请改用returns
:
const dbStub = sinon.stub(db, 'func').returns(Promise.resolve(null))
我在设置
noLocking
选项时遇到问题。文档声明它可以在初始化后设置,但是如果我使用db.$config.options.noLocking = true
设置它,则会发生相同的错误。但是,如果我在database.js init选项中设置它,它可以正常工作。
来自Initialization Options的作者......
这是因为此时noLocking
只会影响任务和事务。由于协议的db
级别仅启动一次,因此在库初始化后设置noLocking
不会影响它。
我刚刚更新了pg-promise以澄清它:
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.