如何使用 HttpTestingController 测试 Promise?

SWe*_*eko 1 unit-testing angular

在 Angular 2 应用程序中,我有一个数据服务,它将 http observables 转换为 Promise,以便使用 async/await 的优点,如下所示:

async getCustomer(id: number): Promise<Customer> {
   return await this._http.get<Customer>(`${this.serverUrl}/customer/${id}`).toPromise();
}
Run Code Online (Sandbox Code Playgroud)

这是可操作的,看起来和工作都很棒。

我之前的单元测试使用了MockBackend类似的东西

mockBackend.connections.subscribe(c => {
   expect(c.request.url).toBe(`${serverUrl}/customer/${id}`);
   let response = new ResponseOptions({ body: mockResponseBody });
   expect(c.request.method).toBe(RequestMethod.Get);
   c.mockRespond(new Response(response));
});

let actual = await service.getCustomer(id);
Run Code Online (Sandbox Code Playgroud)

然而,现在当我尝试这样的事情时

httpMock = TestBed.get(HttpTestingController);
// ... 1
let actual = await service.getCustomer(id);
// ... 2
Run Code Online (Sandbox Code Playgroud)

我陷入了先有鸡还是先有蛋的境地。在提供模拟请求之前,该getCustomer方法不会返回,并且在触发 http 调用之前我无法使用httpMock.expectOneor 。 因此,如果我将调用放入 [1],我会收到预期失败,如果我将其放入 [2],则会收到超时错误:(httpMock.match
httpMock

有没有解决的办法?

Tam*_*dus 5

我不知道TestBed具体是如何运作的。getCustomer我不明白为什么它会阻止您在调用之前安装模拟。您应该使用一个允许您这样做的框架。

但目前的设置是可能的:只需推迟等待承诺即可!

httpMock = TestBed.get(HttpTestingController);
let customerPromise = service.getCustomer(id);
let request = httpMock.expectOne('http://myurl.com'); 
let actual = await customerPromise;
Run Code Online (Sandbox Code Playgroud)