未处理的拒绝错误。 即使testing通过

我正在testing这个function:

UserController.prototype.getDashboard = function getDashboard(req, res, next) { let pages, user; return this.User.findById(req.user.id) .populate('club') .execAsync() .then(dbUser => { user = dbUser; FB.setAccessToken(user.token); return FB.getAsync('me/accounts') }) .then(fbPages => { pages = fbPages.data; return Promise.all(pages.map(page => { return FB.getAsync(`${page.id}/events`) .then(events => events) .catch(e => next(Boom.wrap(e))); })) }) .then(events => { let entity = { user, pages: _.map(pages, (page, i) => _.assign({}, page, { events: events[i].data })) }; return res.send(entity); }) .catch(err => next(Boom.wrap(err))); }; 

但是,当我testing它,即使它通过,我得到Unhandled rejection Error

这是我的testing:

  it('handles errors', (done) => { let mockError = new Error('test-error'); let mockRequest = { user: { id: mockUser._id }}; let mockNext = td.function(); let capture = td.matchers.captor(); td.replace(FB, 'getAsync'); td.when(FB.getAsync('me/accounts')) .thenReturn(Promise.resolve(usersTestData.getDashboard.pages)); td.when(FB.getAsync(`1769754093273789/events`)) .thenReturn(Promise.resolve(usersTestData.getDashboard.events[0])) // Promise rejection was handled asynchronously td.when(FB.getAsync(`731033223716085/events`)) .thenReturn(Promise.reject(mockError)) td.when(mockNext(Boom.wrap(mockError))) .thenDo(() => { done() }); controller.getDashboard(mockRequest, _.noop, mockNext); }); 

怪异的部分,是它通过。 所以mockNext被调用了我所期望的,但是我得到了未处理拒绝的控制台日志。 我试图处理每个值映射的.catch ,但它仍然显示相同的错误(警告?)。

我正在使用蓝鸟承诺,mongoose(promisified)和testdouble。 顺便说一句,这是从控制台运行testing后的日志:

 dashBoard Unhandled rejection Error: test-error ✓ handles errors 

经过大量的试验和错误,我发现发生了什么事情。 问题与testdouble API .thenReturn()

如果.thenReturn(Promise.reject(...))出现错误,我configurationtd使用蓝鸟承诺,并使用他们的API承诺.thenReject(...) 。 结果testing代码将是:

 td.config({ promiseConstructor: require('bluebird') }); it('handles errors', (done) => { let mockError = new Error('test-error'); let mockRequest = { user: { id: mockUser._id }}; let mockNext = td.function(); let capture = td.matchers.captor(); td.replace(FB, 'getAsync'); td.when(FB.getAsync('me/accounts')) .thenReturn(Promise.resolve(usersTestData.getDashboard.pages)); td.when(FB.getAsync(`1769754093273789/events`)) .thenResolve(usersTestData.getDashboard.events[0]) td.when(FB.getAsync(`731033223716085/events`)) .thenReject(mockError) td.when(mockNext(Boom.wrap(mockError))) .thenDo(() => { done() }); controller.getDashboard(mockRequest, _.noop, mockNext); }); 

这个testing不会有任何警告。

我想这个问题是与

 td.when(FB.getAsync(`731033223716085/events`)) .thenReturn(Promise.reject(mockError)) 

如果getAsync函数从不被调用,被拒绝的promise不会被使用(并且没有error handling器被链接到它)。 你可以通过自己添加一个处理程序来告诉它忽略它:

 function ignore(e) {} function ignoredRejection(e) { var p = Promise.reject(e); p.catch(ignore); return p; } 

 td.when(FB.getAsync(`731033223716085/events`)) .thenReturn(ignoredRejection(mockError))