У меня есть следующая функция для тестирования:
// ...
const local = new WeakMap();
export default class User {
// ...
async password(password) {
if (!password) return local.get(this).get('hash'); // remove this for security reasons!
if (password.length < 6) throw new Error('New password must be at least 6 characters long');
if (!password.match(passwordPattern)) throw new Error(`New password must match ${passwordPattern}`);
local.get(this).set('hash', await Password.hash(password));
}
// ...
}
Теперь я хочу протестировать эту функцию с помощью mocha, chai и chai-as-promised выполняют этот тест -кейс:
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import User from '../../../server/User';
chai.use(chaiAsPromised);
const expect = chai.expect;
describe('.password()', () => {
const testuser = new User({username: 'Testuser', password: '123abc'});
// FINDME
it(`should throw when too short`, () => {
return expect(testuser.password('1a')).to.eventually.throw();
});
// ...
});
Найдите комментарий // FINDME
в приведенном выше коде, чтобы получить контекст, на который я ссылаюсь.
Итак, что происходит, так это то, что тесты не ждут завершения асинхронной функции password()
. Как я выяснил, асинхронные функции ECMAScript7 сразу же возвращают thenable, так что все должно быть в порядке, поскольку chai-as-promised использует именно эту функцию. Я предполагаю, что асинхронные функции не выбрасывают ошибки в это указанное обещание, а выбрасывают их в саму включающую функцию, не имея возможности захватить ее через expect()
.
Для нетерпеливых: я транспилирую этот код на лету с помощью babel, используя следующую команду:
babel-node --experimental node_modules/mocha/bin/_mocha --watch --recursive -R spec --check-leaks
Обновление для Babel 6:
Используя babel-node 6.4.0, сработало следующее:
npm install --save-dev babel-preset-stage-0
Затем запустите:
./node_modules/.bin/babel-node --presets stage-0 node_modules/mocha/bin/_mocha --
recursive -R spec --check-leaks