JestJs不等待调用包装异步/等待

时间:2020-03-14 18:28:13

标签: typescript async-await jestjs

我有以下课程:

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);

 }
}

笑话测试如下:

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现在返回一个承诺。关于我在这里可能会缺少的任何想法?

1 个答案:

答案 0 :(得分:1)

测试失败,因为在等待的行完成之前,似乎没有停止在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. 开玩笑说:-(

这是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);
});