用摩卡测试失败的承诺'内置的promise支持

testing failed promises with mocha's built-in promise support

本文关键字:内置 promise 支持 承诺 摩卡 测试 失败      更新时间:2024-05-07

我应该如何用mocha和chai测试我的承诺失败了?

我很困惑,因为我最初认为我应该使用"承诺的摩卡",但该包现在已被弃用(我使用的是mocha 2.1.0),并建议只需使用mocha中内置的promise测试即可。请参阅:https://github.com/domenic/mocha-as-promised

另一篇帖子建议取消对it()回调-我不确定为什么,因为我理解传入"done"参数是表示测试异步测试。请参阅:如何正确地用摩卡和柴来测试承诺?

不管怎样,我已经试着把我的问题减少到下面的代码中了——请帮我修改一下,这样我就可以测试我的承诺是否真的失败了。

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

更多的挖掘,似乎正确的方法是添加一个额外的捕获块,比如…

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

我对其他想法感兴趣,或者确认这是好的…谢谢。

更新:

Ben-我现在明白你在说什么了,特别是在Benjamin G.的简短但有用的评论之后。

总结:

当您传入done参数时,测试将通过调用done()函数来触发它的"完成度";

如果不传入done参数,它通常只适用于同步调用。然而如果返回一个promise,mocha框架(mocha>1.18)将捕获任何通常会被吞噬的故障(根据promise规范)。这是一个更新版本:

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

您可以返回一个promise来表示测试是异步的:

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

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