异步代码

优质
小牛编辑
133浏览
2023-12-01

使用Mocha测试异步代码并不简单!只需在测试完成后调用回调。通过添加一个回调(通常命名doneit(),Mocha将知道它应该等待调用此函数来完成测试。此回调接受Error实例(或其子类)伪值; 其他任何事情都会导致测试失败。

describe('User', function() {
describe('#save()', function() {
  it('should save without error', function(done) {
    var user = new User('Luna');
    user.save(function(err) {
      if (err) done(err);
      else done();
    });
  });
});
});

为了使事情变得更容易,done()回调也接受一个Error实例(即new Error()),所以我们可以直接使用它:

describe('User', function() {
describe('#save()', function() {
  it('should save without error', function(done) {
    var user = new User('Luna');
    user.save(done);
  });
});
});

使用承诺

或者,done()您可以返回Promise,而不是使用回调。如果您正在测试的API返回promises而不是回调,这将非常有用:

beforeEach(function() {
return db.clear()
  .then(function() {
    return db.save([tobi, loki, jane]);
  });
});
describe('#find()', function() {
it('respond with matching records', function() {
  return db.find({ type: 'User' }).should.eventually.have.length(3);
});
});

后一个例子使用Chai作为承诺用于流利的承诺断言。

在Mocha v3.0.0及更新版本中,返回a Promise 调用done()将导致异常,因为这通常是一个错误:

const assert = require('assert');
it('should complete this test', function (done) {
return new Promise(function (resolve) {
  assert.ok(true);
  resolve();
})
  .then(done);
});

上述测试将失败Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.。在v3.0.0之前的版本中,done()有效地忽略了调用。

使用async / await

如果你的js运行环境支持async / await,你也可以像下面这样写异步测试。

beforeEach(async function() {
await db.clear();
await db.save([tobi, loki, jane]);
});
describe('#find()', function() {
it('responds with matching records', async function() {
  const users = await db.find({ type: 'User' });
  users.should.have.length(3);
});
});