Javascript 在 Mocha/Chai 中测试被拒绝的承诺
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31845329/
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
Testing rejected promise in Mocha/Chai
提问by cyberwombat
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 ...
未处理的拒绝错误:Boo ...
With non promise errors I have used bind to test to prevent the error from being thrown until Chai could wrap and test:
对于非承诺错误,我使用 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.
类型错误: [Function] is not a thenable.
What is the correct way to test for this?
对此进行测试的正确方法是什么?
采纳答案by rrowland
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:
看起来您还必须将现有的 catch 移出一个街区:
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');
});
回答by fearless_fool
(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 来测试Promiseresolve
和reject
case 的方法:
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
没有chai-as-promise
You can accomplish the same without chai-as-promised like this:
你可以在没有 chai-as-promised 的情况下完成同样的事情:
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'); })
;
});
回答by Sylvain Leroux
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 timesince 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
回答by Shankar Chaudhary
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
编写 mocha 代码如下
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 世界的新手