7

我想用HttpClientTestingModule. 在我将 rxjs 添加retry(2)到 HTTP 调用之前,这可以正常工作。然后,测试明显抱怨发现了一个意外的请求:

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

但是现在,我不知道如何使用以下命令来期待两个请求HttpTestingController

服务.ts

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

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

服务规范.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

4

1 回答 1

11

Angular 的基础 - HttpClient - retry()状态:

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

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

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

于 2018-03-26T20:14:05.717 回答