如何使用 mocha/chai/chai-as-promised 测试 ES7 异步函数
How to test an ES7 async function using mocha/chai/chai-as-promised
我有以下功能要测试:
// ...
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 and 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 异步函数立即 return 一个 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
我们通过将 eventually.throw()
替换为 chai-as-promised 提供的 .be.rejected
来解决这个问题,因为 async function
总是 returns 一个 Promise。起初我并不清楚这一点。如果愿意,请查看 github 上的讨论。
我有以下功能要测试:
// ...
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 and 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 异步函数立即 return 一个 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
我们通过将 eventually.throw()
替换为 chai-as-promised 提供的 .be.rejected
来解决这个问题,因为 async function
总是 returns 一个 Promise。起初我并不清楚这一点。如果愿意,请查看 github 上的讨论。