我和同事在Jest测试中争论了done()。
他在JavaScript方面的经验要比在我之前高出几个数量级,并且我是在async / await被普遍接受之后加入的,而且我来自.NET环境,所以我习惯了。
我这样写测试:
it("should return 200 OK for POST method", async () => {
await request(app).post("SOMEENDPOINT")
.attach("file", "file")
.expect(200);
});
他习惯于兑现 promise ,因此会这样写测试:
it("should return 200 OK for POST method", (done) => {
request(app).post("SOMEENDPOINT")
.attach("file", "file")
.expect(200, done);
});
我对async / awiat的 push 对他没问题,但坚持认为我必须包括done,以便我要么在做他的版本修改版本:
it("should return 200 OK for POST method", async (done) => {
await request(app).post("SOMEENDPOINT")
.attach("file", "file")
.expect(200, done);
});
要么:
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();
});
虽然我认识到将done()作为参数包含进来是完全必要的,但我冒犯了这种情况,在这种情况下使用async / await完全没有必要。
请求是supertest.request。
我的问题是,我需要在asnyc / await中完全使用完成吗?
最佳答案
在同一测试函数上不再需要done
和async
。选择一个或另一个。
实际上,在您的特定示例中不需要await
; async
足以指定该函数返回promise,并且当它返回时,Jest知道等待其解析:
it("should return 200 OK for POST method", async () => {
request(app).post("SOMEENDPOINT")
.attach("file", "file")
.expect(200)
;
});
返回没有async
的promise也可以:it("should return 200 OK for POST method", () => {
return request(app).post("SOMEENDPOINT")
.attach("file", "file")
.expect(200)
;
});
这意味着我们始终可以手动构建并返回async
或done
的promise。在这种特殊情况下,这是多余的,因为我们已经 promise 要返回,但是以下模式是可能的,即使仅出于说明目的: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))
;
});
});
done
通常用于测试异步回调(请考虑fs
模块中的基本Node库实用程序)。在这些情况下,添加done
参数并在回调中调用它比手工分配回调更优雅。请注意,
done
可以接受被视为错误的参数(请参见docs)。这应该放在任何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))
;
});