承诺与摩卡:完成()之前与否?

时间:2017-08-08 16:03:21

标签: javascript promise mocha

我正在阅读some tutorials on promise tests in mocha。有一段代码:

before(function(done) {
  return Promise.resolve(save(article)).then(function() {
    done();
  });
});

为什么done()then()的{​​{1}}中进行了调用?上述代码与以下代码有什么区别:

before()

由于

更新

我的问题是与以下代码进行比较:

before(function(done) {
  return Promise.resolve(save(article));
});

抱歉打字错误。

3 个答案:

答案 0 :(得分:2)

带有before挂钩的第一个代码段会返回承诺调用done。在Mocha 3.x及更高版本中,它将导致此错误:

Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

过去,如果您使用done并返回一个承诺并不特别重要,但最终Mocha开发人员认为指定done 返回一个承诺只是意味着测试设计师犯了一个错误,最好让Mocha调整适合而不是默默地允许它。

在你的第二个片段中,你有done参数并返回一个promise,但是Mocha仍然会等待done被调用并且会超时。 (它确实应该检测到这个参数并像第一种情况一样引发错误,但它并没有......)

通常,如果您正在测试产生承诺的异步操作,则返回承诺比使用done更简单。以下是说明问题的示例:

const assert = require("assert");

// This will result in a test timeout rather than give a nice error
// message.
it("something not tested properly", (done) => {
    Promise.resolve(1).then((x) => {
        assert.equal(x, 2);
        done();
    });
});

// Same test as before, but fixed to give you a good error message
// about expecting a value of 2. But look at the code you have to
// write to get Mocha to give you a nice error message.
it("something tested properly", (done) => {
    Promise.resolve(1).then((x) => {
        assert.equal(x, 2);
        done();
    }).catch(done);
});

// If you just return the promise, you can avoid having to pepper your
// code with catch closes and calls to done.
it("something tested properly but much simpler", () => {
    return Promise.resolve(1).then((x) => {
        assert.equal(x, 2);
    });
});

关于异步操作的完成,无论您使用的是itbeforebeforeEachafter还是afterEach,它的工作原理都是一样的尽管我给出的例子是it,但同样适用于所有钩子。

答案 1 :(得分:0)

在这种特殊情况下,没有功能差异。回调通常称为done,用于在使用回调时处理异步测试。返回Promise就足够了,但请注意,您无法定义done回调,因为测试套件会等到它被调用。如果无法轻松返回done,请使用Promise。在你的情况下,第二个测试将是无限的,因为你定义了done,你从未实际调用过。

答案 2 :(得分:0)

我不确定我是否100%理解这个问题,但是在调用done之前测试不会开始。

 beforeEach(function(done) {
    setTimeout(function() {
      value = 0;
      done();
    }, 1);
  });

直到在上面的beforeEach调用中调用done函数之后,才会开始此测试。在完成调用之前,此规范将无法完成。

  it("should support async execution of test preparation and expectations", function(done) {
    value++;
    expect(value).toBeGreaterThan(0);
    done();
  });

您不必在示例中完成传递,只需:

before(function() {
  return Promise.resolve(save(article));
});

如果你传递done,测试运行器将在继续之前被调用,否则它可能会抛出超时错误。