所以,我在测试一个依赖于事件发射器的组件。为此,我想出了一个解决方案,使用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”,尽管reject函数正在被调用,因为它会立即显示消息“assertionError:Promise Error"
(Node:25754)UnhandledPromiseRejectionWarning:UnhandledPromiseRejectionWarning:UnhandledPromiseRejection(rejection ID:2):AssertionError:promise Error:{Object(message,showDiff,。。。)}应为
然后,两秒钟后我
错误:超时2000ms。确保在此测试中调用了done()回调。
null
null
null
.catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
如果断言失败,它将抛出一个错误。此错误将导致永远不会调用
“未处理的承诺拒绝”也是由失败的断言引起的,因为如果在
null
像这样:
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');
});
});
我在和Sinon打短板的时候出现了这个错误。
修复方法是在解析或拒绝带有存根的承诺时使用npm包sinon-as-promedied。
null
sinon.stub(Database, 'connect').returns(Promise.reject( Error('oops') ))
null
require('sinon-as-promised');
sinon.stub(Database, 'connect').rejects(Error('oops'));
null
参见http://clarkdave.net/2016/09/node-v6-6-and-asynchronously-handled-promise-rejections
Mocha中的断言库通过在断言不正确的情况下抛出错误来工作。抛出错误会导致拒绝的承诺,即使在提供给
.catch((error) => {
assert.isNotOk(error,'Promise error');
done();
});
在上面的代码中,被对象的
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');
})).then(done,done);
});
在Mocha中测试承诺时使用。then(DoneDone)的想法值得称赞。