Sinon 从中间件中取出模块的功能
Sinon stub out module's function from a middleware
基于,我还需要测试一个同样使用db-connection.js
文件的中间件。中间件文件将如下所示:
const dbConnection = require('./db-connection.js')
module.exports = function (...args) {
return async function (req, res, next) {
// somethin' somethin' ...
const dbClient = dbConnection.db
const docs = await dbClient.collection('test').find()
if (!docs) {
return next(Boom.forbidden())
}
}
}
,数据库连接文件不改,即:
const MongoClient = require('mongodb').MongoClient
const dbName = 'test'
const url = process.env.MONGO_URL
const client = new MongoClient(url, { useNewUrlParser: true,
useUnifiedTopology: true,
bufferMaxEntries: 0 // dont buffer querys when not connected
})
const init = () => {
return client.connect().then(() => {
logger.info(`mongdb db:${dbName} connected`)
const db = client.db(dbName)
})
}
/**
* @type {Connection}
*/
module.exports = {
init,
client,
get db () {
return client.db(dbName)
}
}
中间件的工作原理是传递字符串列表(字符串是角色),我必须查询数据库并检查是否有每个角色的记录。如果记录存在,我将 return next()
,而如果记录不存在,我将 return next(Boom.forbidden())
(下一个函数带有来自 Boom 模块的 403 状态代码) .
根据上面的细节,如果记录存在与否,如何测试中间件的return值呢?这意味着我必须准确断言 next()
和 next(Boom.forbidden)
。
基于 。您可以为 req
、res
对象和 next
函数创建存根。
例如(不运行,但应该可以。)
const sinon = require('sinon');
describe('a', () => {
afterEach(() => {
sinon.restore();
});
it('should find some docs', async () => {
process.env.MONGO_URL = 'mongodb://localhost:27017';
const a = require('./a');
const dbConnection = require('./db-connection.js');
const dbStub = {
collection: sinon.stub().returnsThis(),
find: sinon.stub(),
};
sinon.stub(dbConnection, 'db').get(() => dbStub);
const req = {};
const res = {};
const next = sinon.stub();
const actual = await a()(req, res, next);
sinon.assert.match(actual, true);
sinon.assert.calledWithExactly(dbStub.collection, 'test');
sinon.assert.calledOnce(dbStub.find);
sinon.assert.calledOnce(next);
});
});
基于db-connection.js
文件的中间件。中间件文件将如下所示:
const dbConnection = require('./db-connection.js')
module.exports = function (...args) {
return async function (req, res, next) {
// somethin' somethin' ...
const dbClient = dbConnection.db
const docs = await dbClient.collection('test').find()
if (!docs) {
return next(Boom.forbidden())
}
}
}
,数据库连接文件不改,即:
const MongoClient = require('mongodb').MongoClient
const dbName = 'test'
const url = process.env.MONGO_URL
const client = new MongoClient(url, { useNewUrlParser: true,
useUnifiedTopology: true,
bufferMaxEntries: 0 // dont buffer querys when not connected
})
const init = () => {
return client.connect().then(() => {
logger.info(`mongdb db:${dbName} connected`)
const db = client.db(dbName)
})
}
/**
* @type {Connection}
*/
module.exports = {
init,
client,
get db () {
return client.db(dbName)
}
}
中间件的工作原理是传递字符串列表(字符串是角色),我必须查询数据库并检查是否有每个角色的记录。如果记录存在,我将 return next()
,而如果记录不存在,我将 return next(Boom.forbidden())
(下一个函数带有来自 Boom 模块的 403 状态代码) .
根据上面的细节,如果记录存在与否,如何测试中间件的return值呢?这意味着我必须准确断言 next()
和 next(Boom.forbidden)
。
基于 req
、res
对象和 next
函数创建存根。
例如(不运行,但应该可以。)
const sinon = require('sinon');
describe('a', () => {
afterEach(() => {
sinon.restore();
});
it('should find some docs', async () => {
process.env.MONGO_URL = 'mongodb://localhost:27017';
const a = require('./a');
const dbConnection = require('./db-connection.js');
const dbStub = {
collection: sinon.stub().returnsThis(),
find: sinon.stub(),
};
sinon.stub(dbConnection, 'db').get(() => dbStub);
const req = {};
const res = {};
const next = sinon.stub();
const actual = await a()(req, res, next);
sinon.assert.match(actual, true);
sinon.assert.calledWithExactly(dbStub.collection, 'test');
sinon.assert.calledOnce(dbStub.find);
sinon.assert.calledOnce(next);
});
});