如何使用mocha/chai/chai-as-promised测试ES7异步函数

ker*_*nel 5 javascript testing bdd async-await ecmascript-7

我有以下功能来测试:

// ...
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));
  }

  // ...

}
Run Code Online (Sandbox Code Playgroud)

现在我想用mocha,chaichai-as- promise来测试这个函数做这个测试用例:

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();
  });

  // ...

});
Run Code Online (Sandbox Code Playgroud)

// 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
Run Code Online (Sandbox Code Playgroud)

然后运行:

./node_modules/.bin/babel-node --presets stage-0 node_modules/mocha/bin/_mocha --    
recursive -R spec --check-leaks
Run Code Online (Sandbox Code Playgroud)

ker*_*nel 8

我们通过更换解决了这个问题eventually.throw().be.rejected所提供柴作为许诺的,因为一个async function总是返回的承诺.首先,我不清楚这一点.如果你愿意,可以看一下关于github的讨论.