首页 > 解决方案 > 修改后的护照-jwt的摩卡测试中的UnhandledPromiseRejectionWarning

问题描述

我目前正在研究一个以数组形式接受多个 jwks 提供程序的 passport-jwt 分支。

它实际上运行良好,但我在自动化测试方面遇到了问题,使用现有的 passport-jwt 测试,因为它应该完全向后兼容。

我的存储库在这里:https ://github.com/MeStrak/passport-jwt/tree/9ab3f2d8e99079160ff1a56fd30078c1ec337dee (该链接指向当前的 repo 版本以供将来参考,因为我仍在重构新代码的某些部分)。

与passport-jwt相比的基本实现变化是:

现在运行时npm test我有 54 次通过,3 次失败。所有失败都具有相同的性质,如下例所示:

handling failing jwt
(node:9620) UnhandledPromiseRejectionWarning: Error: Strategy#error should not be called
    at JwtStrategy.strategy.error (/workspace/passport-jwt/node_modules/chai-passport-strategy/lib/test.js:124:33)
    at /workspace/passport-jwt/lib/strategy.js:131:30

最后是这个输出:

  1) Strategy
       handling failing jwt
         "before all" hook for "should not call verify":
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/workspace/passport-jwt/test/strategy-validation-test.js)
      at listOnTimeout (internal/timers.js:554:17)
      at processTimers (internal/timers.js:497:7)

抛出该错误的测试在未修改的代码上通过,所以这个问题肯定与我的实现有关:

    describe('handling failing jwt', function() {
        var strategy, info;
        var verify_spy = sinon.spy();

        before(function(done) {

            strategy = new Strategy({jwtFromRequest: extract_jwt.fromAuthHeaderAsBearerToken(), secretOrKey: 'secret'}, verify_spy);

            // Mock errored verification
            Strategy.JwtVerifier = sinon.stub();
            Strategy.JwtVerifier.callsArgWith(3, new Error("jwt expired"), false);

            chai.passport.use(strategy)
                .fail(function(i) {
                    info = i;
                    done();
                })
                .req(function(req) {
                    req.headers['authorization'] = "bearer " + test_data.valid_jwt.token;
                })
                .authenticate();
        });


        it('should not call verify', function() {
            sinon.assert.notCalled(verify_spy);
        });


        it('should fail with error message.', function() {
            expect(info).to.be.an.object;
            expect(info.message).to.equal('jwt expired');
        });

    });

问题在于直接调用self.erroror的代码区域。self.fail

例如https://github.com/MeStrak/passport-jwt/blob/9ab3f2d8e99079160ff1a56fd30078c1ec337dee/lib/strategy.js#L118

            if (secretOrKeyError) {
                errors.push(secretOrKeyError)
                if (fails.length + errors.length == self._config.length) {
                    if (self._config.length == 1) {
                        errors.length > 0 ? self.error(errors[0]) : self.fail(fails[0]);
                        
                    }

                    const allErrors = errors.concat(fails);
                    if (errors.length > 0) {
                        self.error(allErrors);
                    }
                    else {
                        self.fail(allErrors);
                    }
                }

但是,在调用 _verify 的代码部分(https://github.com/MeStrak/passport-jwt/blob/9ab3f2d8e99079160ff1a56fd30078c1ec337dee/lib/strategy.js#L186),不会发生相同的错误。

现在的问题是我不知道要寻找什么或如何进一步调试它。我认为我所做的更改将是向后兼容的,因此所有测试用例都应该通过,但我想我并不完全理解 async.each 的行为。

任何提示将不胜感激!

标签: javascriptmocha.jspassport.js

解决方案


推荐阅读