JestJs未等待调用包装async/await



我有以下类:

import * as request from "request-promise-native";
export class publisher {
publish(file : string) : PublisherResponse{
let response = PublisherResponse.EmptyResponse;
let options = {};
let promise = this.executeRequest(file , options);
promise.then( value =>  response = value );
return response;
}
async executeRequest(file : string, options : any ) : Promise<PublisherResponse>{
let promise = await request.get("http://someAPI", options);
console.debug("we need to wait for this thing to finish ...")
let response = await promise; 
let data = response.data;
return new new PublisherResponse(file, data);
}
}

Jest测试如下:

test('Should publish a valid single document', async () => {
// Arrange
var documentToPublish = "file1.oas3";
let sut = new publisher(); 
let expectedResponse = new PublisherResponse(documentToPublish, "some-data");
// Act
let actualResponse = sut.publish(documentToPublish);   
// Assert
expect(actualResponse).toEqual(expectedResponse);
});

测试失败,因为异步方法executeRequest中的执行似乎不会停止,直到不可用的行完成。

我最终得到的是一个错误,表明

测试完成后无法登录。你忘了等什么了吗测试中的异步?试图记录"我们需要等待这件事完成…"。

如果我能逃脱惩罚,我现在不想让发布API返回承诺。你知道我在这里会错过什么吗?

测试失败,因为在可重写行完成之前,async方法executeRequest中的执行似乎不会停止。

你说得绝对正确。在async方法中执行不会停止;相反,执行返回给调用者,直到Promise完成。情况如下:

  1. jest调用publish
  2. publish调用executeRequest
  3. executeRequest调用await request.get...
  4. executeRequest将控制权返回给publish
  5. publish将控制权返回给jest
  6. jest运行其预期
  7. await request.get...返回
  8. executeRequest调用console.log...
  9. jest抱怨道:-(

这是async/await(和Promise/then(的工作方式。

如果我能逃脱惩罚,我现在不想让发布API返回承诺。你知道我在这里会错过什么吗?

我的建议是:不要试图从同步函数调用异步函数。相反,让publish返回一个Promise。任何希望publish为即发即弃的代码都可以选择不等待Promise

这会把你的代码改成这样:

export class publisher {
async publish(file: string): Promise<PublisherResponse> {
let response = PublisherResponse.EmptyResponse;
let options = {};
let promise = this.executeRequest(file , options);
await promise.then(value => response = value); // return control to caller
return response;
}
async executeRequest(file: string, options: any): Promise<PublisherResponse> {
let promise = request.get("http://someAPI", options);
console.debug("we need to wait for this thing to finish ...")
let response = await promise; // return control to caller
let data = response.data;
return new new PublisherResponse(file, data);
}
}
test('Should publish a valid single document', async () => {
// Arrange
var documentToPublish = "file1.oas3";
let sut = new publisher(); 
let expectedResponse = new PublisherResponse(documentToPublish, "some-data");
// Act (return control to caller)
let actualResponse = await sut.publish(documentToPublish);   
// Assert
expect(actualResponse).toEqual(expectedResponse);
});

最新更新