如何在 jasmine-node 中正确地使异步单元测试失败

How do I properly fail an async unit test in jasmine-node

为什么以下代码会因超时而失败?看起来 'should' 抛出一个错误并且 done() 永远不会被调用?我该如何编写此测试以使其正确失败而不是让 jasmine 报告超时?

var Promise = require('bluebird');
var should = require('chai').should();
describe('test', function () {
  it('should work', function (done) {
    Promise.resolve(3)
      .then(function (num) {
        num.should.equal(4);
        done();
      });
  });
});

控制台输出为:

c:>茉莉节点规范\

未处理的拒绝 AssertionError:预期 3 等于 4 ... 失败: 1)测试应该有效 信息: 超时:等待规范完成 5000 毫秒后超时

如果您想在 Mocha 套件中使用 Promises,您必须 return 它而不是使用 done() 回调,例如:

describe('test', function () {
  it('should work', function () {
    return Promise.resolve(3)
      .then(function (num) {
        num.should.equal(4);
      });
  });
});

一种更简洁的编写方式是使用 chai-as-promised 模块:

describe('test', function () {
  it('should work', function () {
    return Promise.resolve(3).should.eventually.equal(4);
  });
});

只需确保正确要求它并告诉 chai 使用它:

var Promise = require('bluebird');
var chai = require('chai');
var should = chai.should();
var chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);

使用 .then() 并且仅使用 done()

it('should work', (done) => {
  Promise.resolve(3).then((num) => {
    // your assertions here
  }).catch((err) => {
    expect(err).toBeFalsy();
  }).then(done);
});

使用 .then()done.fail()

it('should work', (done) => {
  Promise.resolve(3).then((num) => {
    // your assertions here
  }).then(done).catch(done.fail);
});

使用 Bluebird 协程

it('should work', (done) => {
  Promise.coroutine(function *g() {
    let num = yield Promise.resolve(3);
    // your assertions here
  })().then(done).catch(done.fail);
});

使用async/await

it('should work', async (done) => {
  try {
    let num = await Promise.resolve(3);
    // your assertions here
    done();
  } catch (err) {
    done.fail(err);
  }
});

async/await.catch()

结合使用
it('should work', (done) => {
  (async () => {
    let num = await Promise.resolve(3);
    // your assertions here
    done();
  })().catch(done.fail);
});

其他选项

您特别询问了 jasmine-node,所以这就是上面示例的内容,但还有其他模块可以让您直接从测试中 return 承诺,而不是调用 done()done.fail() - 参见: