通过测试可能未处理的错误
Possibly unhandled Error with passing tests
我有以下方法:
EventHandler.prototype.handle = function (event) {
var me = this;
return me.processEvent(event).then(function () {
return me.saveLastSeenEventRevision(event);
}).catch(function (err) {
me.logger.debug("First attempt of event process failed, trying recovery");
return me.recoveryStrategy.execute(event,me.processEvent.bind(me)).then(function() {
return me.saveLastSeenEventRevision(event);
});
});
};
我写了这个测试:
describe('when processEvent fails', function() {
beforeEach(function () {
instance.processEvent.returns(Bluebird.reject(new Error('rejection')));
});
describe('when recovery fails', function() {
beforeEach(function () {
instance.recoveryStrategy.execute.returns(Bluebird.reject(new Error('recovery rejected')));
});
it('should not save the revision', function(done) {
instance.handle(event).catch(function() {
sinon.assert.notCalled(instance.saveLastSeenEventRevision);
done();
}).done();
});
});
});
我模拟拒绝 processEvent 方法,在捕获函数中我模拟最终拒绝我的恢复实现。我为此方法编写了更多测试,但设置是相同的。所有测试都按预期通过,但在控制台中我看到此消息:
Possibly unhandled Error: rejection
是否有任何其他方式来处理这些承诺以通过此测试?
测试设置 - mocha / chai / sinon,因为使用了 promise 库 bluebird。
好吧,您正在创建一个明确的拒绝但不在此处处理它:
instance.processEvent.returns(Bluebird.reject(new Error('rejection')));
Bluebird 看到您在此处创建了未处理的拒绝,因此它会通知您。这是因为真正的函数在调用时会 return 拒绝,但 sinon 会提前创建它 - 因此应用程序有未处理的待处理错误位置。您可以通过以下方式关闭它:
Bluebird.onPossiblyUnhandledRejection(function(){});
或者更好的是,使用像 sinon-as-promised 这样的工具,它可以让您:
instance.processEvent.rejects('rejection');
附带说明 - 不要使用愚蠢的 done
语法,Mocha 内置了对 promises 的支持。您可以 return
来自测试的承诺。
因此,问题在于 sinon 存根和设置 return 值。似乎,将被拒绝的承诺作为 return 值传递是 sinon 本身内部的一些评估方式。
有两种选择:
不直接设置 return 值,而是实现将用来代替存根
的函数
sinon.stub(instance, 'processEvent', function() {
return Bluebird.reject(new Error('rejected');
});
使用 sinon-as-promised 库,它允许以下操作:
sinon.stub(instance, 'processEvent').rejects(new Error('rejected'));
我有以下方法:
EventHandler.prototype.handle = function (event) {
var me = this;
return me.processEvent(event).then(function () {
return me.saveLastSeenEventRevision(event);
}).catch(function (err) {
me.logger.debug("First attempt of event process failed, trying recovery");
return me.recoveryStrategy.execute(event,me.processEvent.bind(me)).then(function() {
return me.saveLastSeenEventRevision(event);
});
});
};
我写了这个测试:
describe('when processEvent fails', function() {
beforeEach(function () {
instance.processEvent.returns(Bluebird.reject(new Error('rejection')));
});
describe('when recovery fails', function() {
beforeEach(function () {
instance.recoveryStrategy.execute.returns(Bluebird.reject(new Error('recovery rejected')));
});
it('should not save the revision', function(done) {
instance.handle(event).catch(function() {
sinon.assert.notCalled(instance.saveLastSeenEventRevision);
done();
}).done();
});
});
});
我模拟拒绝 processEvent 方法,在捕获函数中我模拟最终拒绝我的恢复实现。我为此方法编写了更多测试,但设置是相同的。所有测试都按预期通过,但在控制台中我看到此消息:
Possibly unhandled Error: rejection
是否有任何其他方式来处理这些承诺以通过此测试?
测试设置 - mocha / chai / sinon,因为使用了 promise 库 bluebird。
好吧,您正在创建一个明确的拒绝但不在此处处理它:
instance.processEvent.returns(Bluebird.reject(new Error('rejection')));
Bluebird 看到您在此处创建了未处理的拒绝,因此它会通知您。这是因为真正的函数在调用时会 return 拒绝,但 sinon 会提前创建它 - 因此应用程序有未处理的待处理错误位置。您可以通过以下方式关闭它:
Bluebird.onPossiblyUnhandledRejection(function(){});
或者更好的是,使用像 sinon-as-promised 这样的工具,它可以让您:
instance.processEvent.rejects('rejection');
附带说明 - 不要使用愚蠢的 done
语法,Mocha 内置了对 promises 的支持。您可以 return
来自测试的承诺。
因此,问题在于 sinon 存根和设置 return 值。似乎,将被拒绝的承诺作为 return 值传递是 sinon 本身内部的一些评估方式。
有两种选择:
不直接设置 return 值,而是实现将用来代替存根
的函数sinon.stub(instance, 'processEvent', function() { return Bluebird.reject(new Error('rejected'); });
使用 sinon-as-promised 库,它允许以下操作:
sinon.stub(instance, 'processEvent').rejects(new Error('rejected'));