在异步 Jest 测试中是否需要完成?

Jas*_*ues 9 javascript node.js async-await supertest jestjs

done()在 Jest 测试中与一位同事发生争执。

他在 JavaScript 方面的经验比我多几个数量级,我是在async/await被普遍接受之后加入的,加上来自 .NET 环境,所以我已经习惯了。

我写我的测试是这样的:

it("should return 200 OK for POST method", async () => {
    await request(app).post("SOMEENDPOINT")
      .attach("file", "file")
      .expect(200);
});
Run Code Online (Sandbox Code Playgroud)

他更习惯于承诺,所以会像这样编写他的测试:

it("should return 200 OK for POST method", (done) => {
  request(app).post("SOMEENDPOINT")
    .attach("file", "file")
    .expect(200, done);
});
Run Code Online (Sandbox Code Playgroud)

他对我推送到async/ 没问题await,但坚持我必须包含done,这样我要么做他的版本修改版本:

it("should return 200 OK for POST method", async (done) => {
  await request(app).post("SOMEENDPOINT")
    .attach("file", "file")
    .expect(200, done);
});
Run Code Online (Sandbox Code Playgroud)

或者:

it("should return 200 OK for POST method", async (done) => {
    const res = await request(app).post("SOMEENDPOINT")
     .attach("file", "file");
    
    expect(res.status).toBe(200);
    done();
});
Run Code Online (Sandbox Code Playgroud)

虽然我承认done()当它作为参数包含时调用是完全必要的,但我的印象是在这种情况下使用async/时完全没有必要await

请求是supertest.request

我的问题是,我是否需要使用done的所有async/ await

ggo*_*len 10

永远不需要done相同async的测试功能。选择其中之一,或者在这种情况下,直接返回承诺:

it("should return 200 OK for POST method", () =>
  request(app).post("SOMEENDPOINT")
    .attach("file", "file")
    .expect(200)
);
Run Code Online (Sandbox Code Playgroud)

Jest 会返回任何返回的 Promise,这意味着我们始终可以手动构造并返回不带 或 的awaitPromise 。这是多余的,因为我们手头已经有一个承诺,但如果仅用于说明目的,以下模式是可能的:asyncdone

it("should return 200 OK for POST method", () => {
  return new Promise((resolve, reject) => {
    request(app).post("SOMEENDPOINT")
      .attach("file", "file")
      .expect(200, resolve)
      .catch(err => reject(err))
    ;
  });
});
Run Code Online (Sandbox Code Playgroud)

done通常用于测试异步回调(想想fs模块中的基本 Node 库实用程序)。在这些情况下,添加done参数并在回调中调用它比手动承诺回调更优雅。本质上,done这是一种实现承诺化的捷径,可以抽象出new Promise上面所示的样板文件。

请注意,done可以接受被视为错误的参数(请参阅文档)。这应该进入任何catch块,以避免主线代码在调用之前抛出时超时和混乱的错误done

it("should return 200 OK for POST method", done => {
  request(app).post("SOMEENDPOINT")
    .attach("file", "file")
    .expect(200, done)
    .catch(err => done(err))
  ;
});
Run Code Online (Sandbox Code Playgroud)