未处理的拒绝错误。即使测试通过
Unhandled rejection Error. Even though tests are passing
我正在测试这个功能:
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)));
};
但是当我测试它时,即使它通过了,我得到 Unhandled rejection Error
这是我的测试:
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
,但它仍然显示相同的错误(警告?)。
我正在使用 Bluebird promises、mongoose(promisified) 和 testdouble。顺便说一句,这是 运行 测试后来自控制台的日志:
dashBoard
Unhandled rejection Error: test-error
✓ handles errors
经过大量试验和错误后,我发现发生了什么。问题与 testdouble
API .thenReturn()
有关。
如果 .thenReturn(Promise.reject(...))
我将 td
配置为使用 Bluebird 承诺并将其 API 用于承诺 .thenReject(...)
,则会出现错误。结果测试代码为:
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);
});
此测试将在没有警告的情况下运行。
我想问题出在
td.when(FB.getAsync(`731033223716085/events`))
.thenReturn(Promise.reject(mockError))
以防 getAsync
函数从未被调用并且被拒绝的承诺从未被使用(并且没有错误处理程序链接到它)。你可以通过自己添加一个处理程序来告诉它忽略这个:
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))
我正在测试这个功能:
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)));
};
但是当我测试它时,即使它通过了,我得到 Unhandled rejection Error
这是我的测试:
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
,但它仍然显示相同的错误(警告?)。
我正在使用 Bluebird promises、mongoose(promisified) 和 testdouble。顺便说一句,这是 运行 测试后来自控制台的日志:
dashBoard
Unhandled rejection Error: test-error
✓ handles errors
经过大量试验和错误后,我发现发生了什么。问题与 testdouble
API .thenReturn()
有关。
如果 .thenReturn(Promise.reject(...))
我将 td
配置为使用 Bluebird 承诺并将其 API 用于承诺 .thenReject(...)
,则会出现错误。结果测试代码为:
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);
});
此测试将在没有警告的情况下运行。
我想问题出在
td.when(FB.getAsync(`731033223716085/events`))
.thenReturn(Promise.reject(mockError))
以防 getAsync
函数从未被调用并且被拒绝的承诺从未被使用(并且没有错误处理程序链接到它)。你可以通过自己添加一个处理程序来告诉它忽略这个:
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))