使用retry()和HttpClientTestingModule测试HTTP请求

时间:2018-03-22 21:57:21

标签: angular typescript jasmine angular-httpclient angular-test

我想使用HttpClientTestingModule测试HTTP调用错误响应。这可以正常工作,直到我向HTTP调用添加rxjs retry(2)。然后,测试显然抱怨发现了意外的请求:

  

预计没有打开请求,找到1

但是现在,我不知道如何使用HttpTestingController

预期两个请求

service.ts

@Injectable()
export class Service {
  constructor(private http: HttpClient) { }

  get() {
    return this.http.get<any>('URL')
      .pipe(
        retry(2),
        catchError(error => of(null))
      )
  }
}

service.spec.ts

describe('Service', () => {
  let httpTestingController: HttpTestingController;
  let service: Service;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [Service],
      imports: [HttpClientTestingModule]
    });

    httpTestingController = TestBed.get(HttpTestingController);
    service = TestBed.get(Service);
  });

  afterEach(() => {
    httpTestingController.verify();
  });

  it('should handle 404 with retry', () => {
    service.get().subscribe((data: any) => {
      expect(data).toBe(null);
    });
    expectErrorResponse(404);
  });

  function expectErrorResponse(status: number) {
    const requests = httpTestingController.match('URL');
    // fails -> finds only one request
    expect(requests.length).toBe(2);
    requests.forEach(req => req.flush('error', {status, statusText: 'Not Found'}));
  }
});

如果删除expect(requests.length).toBe(2),测试将失败,并显示之前的错误消息。

运行示例

您可以使用此Stackblitz

进行试用

1 个答案:

答案 0 :(得分:7)

The fundamentals of Angular - HttpClient - retry()州:

  

RxJS库提供了几个值得的重试运算符   探索。最简单的是自动调用retry()   重新订阅一个失败的Observable指定的次数。   重新订阅HttpClient方法调用的结果有   重新发出HTTP请求的效果。

因此,每次调用flush时,都会留下一个打开的请求。您只需在服务重试请求时重复请求处理和刷新次数。

&#13;
&#13;
it('can test for 404 error', () => {
  const emsg = 'deliberate 404 error';

  testService.getData().subscribe(
    data => fail('should have failed with the 404 error'),
    (error: HttpErrorResponse) => {
      expect(error.status).toEqual(404, 'status');
      expect(error.error).toEqual(emsg, 'message');
    }
  );

  const retryCount = 3;
  for (var i = 0, c = retryCount + 1; i < c; i++) {
    let req = httpTestingController.expectOne(testUrl);
    req.flush(emsg, { status: 404, statusText: 'Not Found' });
  }
});
&#13;
&#13;
&#13;