如何在 Angular 9 中通过 Jasmine/Karma 正确使用 HttpClientTestingModule

bil*_*por 5 jasmine typescript angular

我们有一个通用服务来发出和接收对后端控制器的调用。在 Angular 4 中,所有测试都有效,但由于新的库和更改,它们不再有效。HttpClientTestingModule我现在正在尝试使用和重写这些HttpTestingController

所以我们的具体类有许多函数,目前我专注于我们的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));

  }
Run Code Online (Sandbox Code Playgroud)

目前在我的规范文件中我有:

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();
        }));
     });
    });
Run Code Online (Sandbox Code Playgroud)

问题是,如果我最初省略了针对 httpTestingController 的最后两行代码,那么我的期望永远不会达到,并且测试工具会显示“未找到期望”。如果我重新引入这两行,那么我会收到一条失败消息,其中指出:

失败:预期有一个针对条件“匹配 URL:测试”的匹配请求,但没有找到。收到的请求为: GET http://localhost:9876/api/User/、 GET http://localhost:9876/api/Config/UiServiceUri、 GET http://localhost:9876/api/User/

然后我将 URL 更改为主 URL,以便测试控制器行变为:

httpTestingController.expectOne('http://localhost:9876/api/User/');
Run Code Online (Sandbox Code Playgroud)

然后我收到一个类似的错误,指出只有一个是预期的,但发现了 2。我猜这是因为我的具体类的构造函数。我应该如何编写这个测试?