承诺和摩卡:before中是否需要使用done()函数?

9

我正在阅读关于使用Promise测试Mocha的一些教程。这里有一段代码:

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

为什么在 before() 中调用 then() 中的 done()?上述代码和以下代码有什么区别:

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

谢谢

更新

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

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

抱歉打错字了。
3个回答

8

第一个带有before钩子的代码片段返回一个Promise并调用done。在Mocha 3.x及以上版本中,这将导致以下错误:

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

过去使用done并返回一个promise可能并不重要,但最终Mocha开发人员认为同时指定done和返回promise只意味着测试设计师犯了一个错误,更好的做法是让Mocha抛出异常而不是默默地允许它。

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

通常,如果你正在测试产生promise的异步操作,最简单的方法是返回promise而不是使用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);
    });
});

关于异步操作的完成,无论是使用 it, before, beforeEach, after 还是 afterEach,它们的工作方式是相同的。因此,即使我给出的示例是使用 it,所有钩子都适用于该示例。


1

我不确定是否完全理解了问题,但是测试只有在调用done之后才会开始。

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

在上面的beforeEach调用中,只有在调用done函数后,此测试才会开始。而此规范将在其done被调用之前无法完成。
  it("should support async execution of test preparation and expectations", function(done) {
    value++;
    expect(value).toBeGreaterThan(0);
    done();
  });

你不必在示例中传递“done”,只需:

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

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

0
在这种情况下,没有功能上的区别。回调函数通常称为done,是用于处理使用回调函数时的异步测试引入的。返回一个Promise就足够了,但请注意,您不能定义done回调函数,因为测试套件将等待它被调用。当您无法轻松返回Promise时,请使用done。在您的情况下,第二个测试将是无限的,因为您定义了done,但实际上从未调用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接