我想测试以下代码:

'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
}


我想测试我的setupQueueenqueueJobconsumeJob方法,以确保它们对AMQP服务器执行正确的操作。

例如,对于setupQueue,我要确保它使用Channel.createConfirmChannel而不是说Channel.createChannel,并且它也使用Channel.assertQueue

但是,我不知道该怎么做。

如果我使用proxyquire模拟amqp变量,则只能监视amqp.connect调用。我可能会对其进行存根处理,以避免击中任何AMQP服务器。但是下面的语句呢?如何点击connchannel对象?

最佳答案

我建议使用依赖注入模式。

在我看来,依赖注入是易于进行单元测试的金钥匙。这不仅适用于此特定测试,还适用于您将要编写的所有测试。

为此,您必须


拆分方法
在那些方法中使用依赖注入
也许为queueManager创建一个构造函数以访问连接
使用SinonJs库进行存根/模拟/间谍。


看起来像这样



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(); })
  })
})

关于node.js - 测试依赖于回调返回的对象的函数调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34440399/

10-16 18:04
查看更多