简体   繁体   English

测试在Mocha / Chai中拒绝了承诺

[英]Testing rejected promise in Mocha/Chai

I have a class that rejects a promise: 我有一个拒绝承诺的课程:

Sync.prototype.doCall = function(verb, method, data) {
  var self = this;

  self.client = P.promisifyAll(new Client());

  var res = this.queue.then(function() {
    return self.client.callAsync(verb, method, data)
      .then(function(res) {
        return;
      })
      .catch(function(err) {    
        // This is what gets called in my test    
        return P.reject('Boo');
      });
  });

  this.queue = res.delay(this.options.throttle * 1000);
  return res;
};

Sync.prototype.sendNote = function(data) {
  var self = this;
  return self.doCall('POST', '/Invoice', {
    Invoice: data
  }).then(function(res) {
    return data;
  });
};

In my test: 在我的测试中:

return expect(s.sendNote(data)).to.eventually.be.rejectedWith('Boo');

However while the test passes it throws the error to the console. 但是,当测试通过时,它会将错误抛出到控制台。

Unhandled rejection Error: Boo ... 未处理的拒绝错误:嘘......

With non promise errors I have used bind to test to prevent the error from being thrown until Chai could wrap and test: 对于非promise错误,我使用bind来测试以防止在Chai可以包装和测试之前抛出错误:

return expect(s.sendNote.bind(s, data)).to.eventually.be.rejectedWith('Boo');

However this does not work with this and returns: 但是这不适用于此并返回:

TypeError: [Function] is not a thenable. TypeError: [Function] is not a thenable.

What is the correct way to test for this? 测试这个的正确方法是什么?

(Disclaimer: This is a good question even for people that do not use Bluebird. I've posted a similar answer here ; this answer will work for people that aren't using Bluebird.) (免责声明:即使对于不使用Bluebird的人来说这也是一个很好的问题。我在这里发布了类似的答案;这个答案适用于那些没有使用Bluebird的人。)

with chai-as-promised 与柴承诺

Here's how you can use chai-as-promised to test both resolve and reject cases for a Promise: 以下是如何使用chai-as-promised来测试Promise的resolvereject案例:

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

without chai-as-promised 没有柴 - 承诺

You can accomplish the same without chai-as-promised like this: 你可以完成同样的事情,而不像这样承诺:

it('resolves as promised', function() {
  return Promise.resolve("woof")
    .then(function(m) { expect(m).to.equal('woof'); })
    .catch(function(e) { throw e })  // use error thrown by test suite
           ;
});

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

I personally use that idiom: 我个人使用那个成语:

it('rejects as promised', function() {
    return Promise.reject("caw")
        .then(
          (m) => { assert.fail('was not supposed to succeed'); }
          (m) => { /* some extra tests here */ }
        );
});

This is one of the rare cases then(onFulfilled, onRejected) (2 arguments) is legitimate to use. 这是极少数情况之一then(onFulfilled, onRejected) (2个参数)是合法使用的。

If you chain .then(reject).catch(onRejected) as suggested in other answers, you end up entering in the catch handler every time since it will catch as well the rejection produced in the preceding then handler--which could cause evergreen tests if you're not careful enough to check that eventuality. 如果要链接.then(reject).catch(onRejected)在其他的答案建议,你最终在进入catch处理每一个时间 ,因为它会赶上以及在前面产生的排斥反应then处理程序-这可能会导致常绿测试如果你不小心检查那种可能性。

You're getting the error because sendNote is being rejected and you're not catching it. 您收到错误是因为sendNote被拒绝而您没有抓住它。

Try: 尝试:

var callPromise = self.doCall('POST', '/Invoice', {
  Invoice: data
}).then(function(res) {
  return data;
});

callPromise.catch(function(reason) {
  console.info('sendNote failed with reason:', reason);
});

return callPromise;

Looks like you'll also have to move your existing catch one block out: 看起来你还必须将现有的一个块移出:

var res = this.queue.then(function() {
  return self.client.callAsync(verb, method, data)
    .then(function(res) {
      return;
    });
  }).catch(function(err) {    
    // This is what gets called in my test    
    return P.reject('Boo');
  });

I have faced the same problem but on doing many hacks I found a solution for testing rejected promises in mocha. 我遇到了同样的问题,但在做了很多黑客攻击时,我找到了一个用于测试mocha中被拒绝的承诺的解决方案。

write mocha code as below 写下摩卡代码如下

it('works with resolved and rejected promises', function() {
 return yourPromiseFunction("paramifrequired")
       .then((result)=>{
            //check with should or expect
       }).catch((result)=>{
            //check with should or expect whether it's rejected with proper result status. set result status in promise function while rejecting accordingly
       })

  });

NOTE:- Hope you find it useful. 注意: - 希望您觉得它很有用。 If you have another idea suggestion do comment me I am newbie exploring the js world 如果你有另一个想法建议,请评论我,我是新手探索js世界

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM