我想测试以下代码:
'use strict';
const amqp = require('amqplib');
const Promise = require('bluebird');
const queueManager = function queueManager() {
const amqp_host = 'amqp://' + process.env.AMQP_HOST || 'localhost';
return {
setupQueue: Promise.method(function setupQueue(queue) {
return amqp.connect(amqp_host)
.then(conn => conn.createConfirmChannel())
.tap(channel => channel.assertQueue(queue));
}),
enqueueJob: Promise.method(function enqueueJob(channel, queue, job) {
return channel.sendToQueue(queue, new Buffer(job));
}),
consumeJob: Promise.method(function consumeJob(channel, queue) {
return channel.consume(queue, msg => msg);
})
};
};
module.exports = {
create: queueManager
}
我想测试我的setupQueue
,enqueueJob
和consumeJob
方法,以确保他们为AMQP服务器做正确的事情。
例如,对于setupQueue
,我想确保它使用Channel.createConfirmChannel
代替Channel.createChannel
,而且Channel.assertQueue
也是如此。
但是,我不知道该怎么做。
如果我使用proxyquire模拟amqp
变量,我将能够监视的是amqp.connect
调用。我可能会将其存根以避免命中任何AMQP服务器。但是下面的陈述呢?如何使用conn
和channel
对象?
答案 0 :(得分:0)
我建议使用依赖注入模式。
在我看来,依赖注入是轻松进行单元测试的黄金票。这不仅适用于此特定测试,而且适用于您正在编写的所有测试。
要完成此任务,您必须
它看起来像这样
var channelFactory = (conn) => conn.createConfirmChannel();
function QueueManager(queue, channelFactory){
this.queue = queue;
this.channelFactory = channelFactory;
}
QueueManager.prototype.setupQueue = () =>
(var scope = this)
.channelFactory()
.then((channel) => (scope.channel = channel).assertQueue(scope.queue);
QueueManager.enqueueJob = (channel, queue, job) => channel.sendToQueue(queue, new Buffer(job));
QueueManager.consumeJob = (channel, queue) => channel.consume(queue, msg => msg);
// Unit tests
describe('setupQueue', () => {
it('should do smth', (done) => {
var host = 'localhost',
conn = new connection(host),
queue = new queue(),
aChannelFactory = channelFactory.bind(queue, conn),
queueManager = new QueueManager(queue, aChannelFactory),
spy = sinon.spy(channel.conn, 'createConfirmChannel');
queueManager
.setupQueue()
.then(() => { assert.spy.calledOnce(); done(); })
.fail((err) => { done(err); })
.finally(() => { spy.restore(); })
})
})