通过测试可能未处理的错误

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 本身内部的一些评估方式。

有两种选择:

  1. 不直接设置 return 值,而是实现将用来代替存根

    的函数
    sinon.stub(instance, 'processEvent', function() {
        return Bluebird.reject(new Error('rejected');
    });
    
  2. 使用 sinon-as-promised 库,它允许以下操作:

    sinon.stub(instance, 'processEvent').rejects(new Error('rejected'));