使用mocha,sinon和node捕获回调结果

时间:2013-12-31 02:37:21

标签: node.js bdd mocha sinon

我正在为我的应用程序编写一个邮件模块,返回一个回调:

(function() {
  "use strict";

  function Mail(opts) {
    // some sode
  }

  Mail.prototype.send = function(config, opts) {
    var transport;
    // server connect options
    config =  { ... };
    // mail body options
    opts = { ... };

    transport = nodemailer.createTransport("SMTP", config);

    transport.sendMail(opts, function(err, res) {
      if (err)
        console.error(err);
      else
        console.log('Message sent');
    });

    // transport.close();
  };

  module.exports = Mail;
}());

我的测试代码包含以下内容:

describe('smtp', function() {
  var opts, config;
  before(function() {
    config = { /* some config data */ };
    opts = { /* mail body */ }; 
    mail = new Mail();
    mail.send(config, opts);
  });
  beforeEach(function() {
    // stub console
    sandbox = sinon.sandbox.create();
    sandbox.stub(console, 'log');
    sandbox.stub(console, 'error');
  });

  afterEach(function() {
    sandbox.restore();
  });

  describe('send mail', function() {
    it('should connect and send mail', function(done) {

      sinon.assert.notCalled(console.error);
      sinon.assert.called(console.log);
      sinon.assert.calledWithExactly(console.log, 'Message sent');

      done();
    });
  });
});

电子邮件已成功发送,但我无法在测试中捕获返回的回调结果:

smtp
  send mail

1 failing

1) Mail smtp send mail should connect and send mail: AssertError: expected log to have been called at least once but was never called
  at Object.fail (/home/gabriel/projects-node/brim/node_modules/sinon/lib/sinon/assert.js:92:25)
  at failAssertion (/home/gabriel/projects-node/brim/node_modules/sinon/lib/sinon/assert.js:53:20)
  at Object.assert.(anonymous function) [as called] (/home/gabriel/projects-node/brim/node_modules/sinon/lib/sinon/assert.js:76:17)
  at Context.<anonymous> (/home/gabriel/projects-node/brim/test/mail.js:78:22)
  at Test.Runnable.run (/home/gabriel/projects-node/brim/node_modules/gulp-mocha/node_modules/mocha/lib/runnable.js:204:15)
  at Runner.runTest (/home/gabriel/projects-node/brim/node_modules/gulp-mocha/node_modules/mocha/lib/runner.js:378:10)
  at /home/gabriel/projects-node/brim/node_modules/gulp-mocha/node_modules/mocha/lib/runner.js:456:12
  at next (/home/gabriel/projects-node/brim/node_modules/gulp-mocha/node_modules/mocha/lib/runner.js:303:14)
  at /home/gabriel/projects-node/brim/node_modules/gulp-mocha/node_modules/mocha/lib/runner.js:313:7
  at next (/home/gabriel/projects-node/brim/node_modules/gulp-mocha/node_modules/mocha/lib/runner.js:251:23)

Message sent

请注意,代码运行后,消息已发送响应会出现。如何改进我的测试代码?

1 个答案:

答案 0 :(得分:0)

您的原始方法实际上并不是非常可测试的,因为当 完成执行时,您无法真正验证

为此,您可能希望使用以下签名重写该方法,添加done回调。

Mail.prototype.send = function(config, opts, done) {
    var transport;
    // server connect options
    config =  { ... };
    // mail body options
    opts = { ... };

    transport = nodemailer.createTransport("SMTP", config);
    transport.sendMail(opts, done);
};

然后你的测试可以create an spy并将其作为done回调传递,并断言间谍函数只被调用一次。