使用mocha的内置承诺支持测试失败的承诺

时间:2015-02-24 19:41:15

标签: javascript node.js promise mocha

我应该如何用摩卡和柴来测试我的承诺失败了?

我很困惑,因为我最初认为我应该使用'mocha-as-promised',但那 包现在已被弃用(我正在使用mocha 2.1.0),并提供建议 只需使用现在内置于mocha中的promise测试。 见:https://github.com/domenic/mocha-as-promised

另一篇文章建议废除“完成”参数 it()回调 - 不确定我理解为什么,因为我的理解 传递'done'参数是表示测试结果的方式 正在异步测试。 见:How do I properly test promises with mocha and chai?

无论如何,我已经尝试将我的问题减少到下面的代码 - 请帮我修改这个,以便我可以测试我的承诺确实失败了。

it.only("do something (negative test)", function (done) {

  var Q = require('q');

  function makePromise() {
    var deferred = Q.defer();
    deferred.reject(Error('fail'));
    return deferred.promise;
  };

  makePromise()
  .then(done, done);

});

3 个答案:

答案 0 :(得分:10)

进一步挖掘,看起来正确的方法是添加一个额外的catch块,就像这样......

it.only("do something (negative test)", function (done) {

  var Q = require('q');

  function makePromise() {
    var deferred = Q.defer();
    deferred.reject(Error('fail'));
    return deferred.promise;
  };

  makePromise()
  .catch(function(e) {
    expect(e.message).to.equal('fail');
  })
  .then(done, done);

});

我对其他想法感兴趣,或确认这样做很好..谢谢。

更新:

本 - 我现在不知道你在说什么,尤其是在本杰明G的简短但有用的评论之后。

总结:

当您传入done参数时,预计测试会通过调用done()函数触发“完成”;

如果未传入done参数,则通常仅适用于同步调用。然而, 如果你 返回 一个承诺,mocha框架(mocha> 1.18)将捕获通常会被吞下的任何失败(根据promises规范)。这是一个更新版本:

it.only("standalone neg test for mocha+promises", function () {

  var Q = require('q');

  function makePromise() {
    var deferred = Q.defer();
    deferred.reject(Error('fail'));
    return deferred.promise;
  };

  return makePromise()
  .catch(function(e) {
    expect(e.message).to.equal('fail');
  });

});

答案 1 :(得分:3)

您可以返回一个承诺,表示测试是异步的:

function something() {
  return Q.reject(Error('fail'));
}

it('should reject', function() {
  return something().then(function() {
    throw new Error('expected rejection');
  },
  function() {
    return 'passed :]';
  });
});

答案 2 :(得分:0)

chai-as-promised为Promises提供了一个干净的测试框架:

$ npm install chai-as-promised

在您的测试文件中:

var chai = require('chai');
var expect = chai.expect;
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);

...

it('resolves as promised', function() {
    return expect(Promise.resolve('woof')).to.eventually.equal('woof');
});

it('rejects as promised', function() {
    return expect(Promise.reject('caw')).to.be.rejectedWith('caw');
});

这感觉干净直观。但你可以完成类似的事情,而不像这样承诺:

it('resolved as promised', function() {
    return Promise.resolve("woof")
        .then(function(m) { expect(m).to.equal('woof'); })
        .catch(function(m) { throw new Error('was not supposed to fail'); })
            ;
});

it('rejects as promised', function() {
    return Promise.reject("caw")
        .then(function(m) { throw new Error('was not supposed to succeed'); })
        .catch(function(m) { expect(m).to.equal('caw'); })
            ;
});