У меня есть следующий тестовый код в NodeJS:
'use strict';
// Example class to be tested
class AuthController {
constructor() {
console.log('Auth Controller test!');
}
isAuthorizedAsync(roles, neededRole) {
return new Promise((resolve, reject) => {
return resolve(roles.indexOf(neededRole) >= 0);
});
}
}
module.exports = AuthController;
И следующий тестовый код мокки:
'use strict';
const assert = require('assert');
const AuthController = require('../../lib/controllers/auth.controller');
describe('isAuthorizedAsync', () => {
let authController = null;
beforeEach(done => {
authController = new AuthController();
done();
});
it('Should return false if not authorized', function(done) {
this.timeout(10000);
authController.isAuthorizedAsync(['user'], 'admin')
.then(isAuth => {
assert.equal(true, isAuth);
done();
})
.catch(err => {
throw(err);
done();
});
});
});
который вызывает следующую ошибку:
1 failing
1) AuthController
isAuthorizedAsync
Should return false if not authorized:
Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (c:\supportal\node_modules\ttm-module\test\controllers\auth.controller.spec.js)
Я попытался увеличить время ожидания мокко-теста по умолчанию до 10 секунд и удостоверился, что обещание решает. Я новичок в мокко. Я что-то упустил?
Проблема в том, что вы не используете асинхронный API mocha правильно. Чтобы вызвать сбой с done
обратным вызовом, вы должны предоставить ошибку в качестве первого аргумента при ее вызове.
Как написано, ваше утверждение в обработчике then
бросает, которое пропускает первый done
вызов и переходит к обработчику catch
. Этот обработчик catch
в свою очередь, перебрасывает ту же ошибку, аналогично не позволяя вам достичь второго done
обратного вызова.
То, что вы получаете, - это необработанное обещание, отклонение и не вызванное done
, приводящее к тайм-ауту теста мокко, возможно, с предупреждающим сообщением об необработанном отказе, в зависимости от того, какую версию узла вы используете.
Самое быстрое исправление заключается в том, чтобы правильно выполнить обратный вызов:
it('Should return false if not authorized', function(done) {
authController.isAuthorizedAsync(['user'], 'admin')
.then(isAuth => {
assert.equal(true, isAuth);
done();
})
.catch(err => {
done(err); // Note the difference
});
});
Более чистым решением будет использование встроенной поддержки обещаний Mocha, возвращая обещанное обещание. Это устраняет необходимость явно обрабатывать случай отказа:
it('Should return false if not authorized', function() {
return authController.isAuthorizedAsync(['user'], 'admin')
.then(isAuth => {
assert.equal(true, isAuth);
});
});