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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28704791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:24:34  来源:igfitidea点击:

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

javascriptnode.jspromisemocha

提问by RoyM

How should I be testing, with mocha and chai, that my promise has failed?

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

I am confused, because I initially thought I should be using 'mocha-as-promised', but that package is now deprecated (I'm using mocha 2.1.0), with the advice to just use the promise testing that's now built into mocha. see: https://github.com/domenic/mocha-as-promised

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

Another post recommends doing away with the 'done' argument to the it() callback - not sure I understand why, since my understanding that passing in the 'done' parameter was the way to signal that a test was being tested asynchronously. see: How do I properly test promises with mocha and chai?

另一篇文章建议取消 it() 回调中的“done”参数——我不确定我明白为什么,因为我理解传递“done”参数是一种表示测试正在被异步测试的方式。请参阅:如何使用 mocha 和 chai 正确测试 promise?

Anyway, I've tried to reduce my issue to the below code - please help me modify this so that I can test that my promise indeed fails.

无论如何,我已经尝试将我的问题简化为以下代码 - 请帮我修改它,以便我可以测试我的承诺确实失败了。

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

});

回答by RoyM

Some more digging, and it appears the right way is to add an additional catch block, like so...

更多的挖掘,看起来正确的方法是添加一个额外的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);

});

I'm interested in alternative ideas, or confirmation that this is fine the way it is.. thanks.

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

UPDATE:

更新:

Ben - I now grok what you were saying, esp. after the terse but helpful comment from Benjamin G.

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

To summarize:

总结一下:

When you pass in a doneparameter, the test is expected to trigger it's 'done-ness' by calling the done()function;

当你传入一个done参数时,测试应该通过调用done()函数来触发它的“完成” ;

When you don't pass in a doneparameter, it normally only works for synchronous calls. However, if you returna promise, the mocha framework (mocha >1.18) will catch any failures that normally would have been swallowed (per the promises spec). Here is an updated version:

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

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

});

回答by Ben

You can return a promise to signal that the test is asynchronous:

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

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

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

回答by fearless_fool

chai-as-promisedprovides a clean testing framework for Promises:

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

$ npm install chai-as-promised

In your test file:

在您的测试文件中:

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

This feels clean and intuitive. But you can accomplish something similar without chai-as-promised like this:

这感觉干净和直观。但是你可以在没有 chai-as-promised 的情况下完成类似的事情:

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