Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

testing - Angular httpTestingController.expectOne throws even though httpClient.get was called

I have this simple function inside a service:

getReports(url: string): Observable<Report[]> {
    return this.http.get<Report[]>(url);
}

My test is as follows:

  it(`should call http request`, function() {
    spyOn(httpClient, 'get');
    const fakeUrl = 'https://reports.url/';
    service.getReports(fakeUrl);

    expect(httpClient.get).toHaveBeenCalledWith(fakeUrl);
    const req = httpTestingController.expectOne(fakeUrl);
  });

The first expectation passes (so httpClient.get was called with the fakeUrl, but the controller's expectOne failed:

Expected one matching request for criteria "Match URL: https://reportss.url/", found none.

Any idea why angular's testing controller doesn't recognize my call?

Thanks!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After a lot of trial and error it seems that the issue stems from the fact that expectOne (and matchOne at that) only work if there's a subscriber to the http request. So this will throw an error:

httpClient.get(fakeUrl);
const request = await httpTestingController.expectOne(fakeUrl);

But this will work:

httpClient.get(fakeUrl)
   .subscribe(() => {});
const request = await httpTestingController.expectOne(fakeUrl);

This happens because the http observable is considered cold as long as there are no subscribers to it. The moment you subscribe to the observable, the observable becomes hot or open and then expectOne can find it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...