typescript - Cum să folosești corect HttpClientTestingModule în Angular 9 cu Jasmine/Karma


Avem un serviciu generic pentru a efectua și a primi apeluri către controllerele backend. În Angular 4 toate testele funcționau, dar din cauza noilor biblioteci și a schimbărilor acestea nu mai funcționează. Acum încerc să le rescriu folosind HttpClientTestingModule și HttpTestingController.

Deci, clasa noastră concretă are mai multe funcții și, pentru moment, mă concentrez pe metoda noastră getRequest:

constructor(
    private configService: ConfigService,
    private userService: UserService,
    private httpClient: HttpClient,
    private errorMapperService: ErrorMapperService) {
  }

  public getRequest(uri: string): Observable<any> {

    const fullUri = this.buildServiceUri(uri);
    const requestHeaders = this.getDefaultRequestHeadersObservable();

    return forkJoin(fullUri, requestHeaders)
      .pipe(flatMap((results: [string, HttpHeaders]) => this.httpClient.get(results[0], { withCredentials: true, headers: results[1] })),
        catchError(this.errorMapperService.handleError));

  }

În acest moment, în fișierul meu de specificații am:

fdescribe('Api Service', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientModule,
        HttpClientTestingModule
      ],
      providers: [
        { provide: ApiService },
        { provide: ConfigService },
        { provide: ErrorMapperService },
        { provide: UserService }
      ]
    });
  });

  describe('getRequest', () => {

    const uiServiceUri: string = 'uiServiceUri';
    const expectedResponse: any = { data: '1234', myDate: new Date(2017, 0, 1, 0, 0, 0) };
    const user = new User();
    user.userSession = '<SESSIONTOKEN>';

    let configService: ConfigService;
    let userService: UserService;
    let apiService: ApiService;
    let errorMapperService: ErrorMapperService;

    let httpTestingController: HttpTestingController;

    beforeEach(() => {
      configService = TestBed.get(ConfigService);
      userService = TestBed.get(UserService);
      apiService = TestBed.get(ApiService);
      errorMapperService = TestBed.get(ErrorMapperService);

      httpTestingController = TestBed.get(HttpTestingController);

    });

    describe('with response object',
      () => {

        it('Gets expected response and converts dates to date objects', async(() => {
          apiService.getRequest('test')
            .subscribe((responseObject) => {
              expect(responseObject).toEqual(expectedResponse);
            });

          httpTestingController.expectOne('test').flush(expectedResponse);

          httpTestingController.verify();
        }));
     });
    });

Problema este că, dacă inițial omit ultimele 2 linii de cod împotriva httpTestingController, atunci expect-ul meu nu este niciodată atins și cadrul de testare spune 'nu a fost găsită nicio așteptare'. Dacă reintroduc acele 2 linii, atunci primesc un eșec care afirmă:

Eșuat: Se aștepta o solicitare corespunzătoare criteriilor „Potrivește URL-ul: test”, dar nu a fost găsită niciuna. Solicitările primite sunt: GET http://localhost:9876/api/User/, GET http://localhost:9876/api/Config/UiServiceUri, GET http://localhost:9876/api/User/.

Așadar, schimb URL-ul cu cel principal astfel încât linia controller-ului de test să devină:

httpTestingController.expectOne('http://localhost:9876/api/User/');

atunci primesc o eroare similară care spune că doar unul era așteptat, dar s-au găsit 2. Presupun că acest lucru se datorează constructorului clasei concrete. Cum ar trebui să scriu acest test?