javascript – NodeJS UnhandledPromiseRejectionWarning
作者:互联网
所以,我正在测试一个依赖于事件发射器的组件.为此,我想出了一个使用Promise with Mocha Chai的解决方案:
it('should transition with the correct event', (done) => {
const cFSM = new CharacterFSM({}, emitter, transitions);
let timeout = null;
let resolved = false;
new Promise((resolve, reject) => {
emitter.once('action', resolve);
emitter.emit('done', {});
timeout = setTimeout(() => {
if (!resolved) {
reject('Timedout!');
}
clearTimeout(timeout);
}, 100);
}).then(((state) => {
resolved = true;
assert(state.action === 'DONE', 'should change state');
done();
}))
.catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
});
});
在控制台上我得到一个’UnhandledPromiseRejectionWarning’,即使拒绝函数被调用,因为它立即显示消息’AssertionError:Promise error’
(node:25754) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 2): AssertionError: Promise error: expected
{ Object (message, showDiff, …) } to be falsy
1) should transition with the correct event
然后,在2秒后我得到了
Error: timeout of 2000ms exceeded. Ensure the done() callback is
being called in this test.
自从执行catch回调以来,这甚至更奇怪.(我认为由于某种原因,断言失败阻止了其余的执行)
现在有趣的是,如果我注释掉assert.isNotOk(错误…),测试运行正常,没有控制台中的任何警告.它执行捕获的意义上仍然“失败”.
但是,我仍然无法理解这些错误.有人可以开导我吗?
解决方法:
问题是由此造成的:
.catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
如果断言失败,则会抛出错误.此错误将导致done()永远不会被调用,因为代码在它之前出错了.这就是造成超时的原因.
“Unhandled promise rejection”也是由失败的断言引起的,因为如果在catch()处理程序中抛出错误,并且没有后续的catch()处理程序,则会吞下错误(如this article中所述) . UnhandledPromiseRejectionWarning警告提醒您注意这一事实.
一般来说,如果你想在Mocha中测试基于promise的代码,你应该依赖Mocha本身可以处理promise的事实.您不应该使用done(),而是从测试中返回一个promise.然后摩卡会捕捉到任何错误.
像这样:
it('should transition with the correct event', () => {
...
return new Promise((resolve, reject) => {
...
}).then((state) => {
assert(state.action === 'DONE', 'should change state');
})
.catch((error) => {
assert.isNotOk(error,'Promise error');
});
});
标签:chai,javascript,node-js,mocha,promise 来源: https://codeday.me/bug/20190919/1812932.html