【问题标题】:Angular ErrorInterceptor unit test not working as expectedAngular ErrorInterceptor 单元测试未按预期工作
【发布时间】:2021-03-26 12:59:56
【问题描述】:

我有一个使用错误拦截器的 Angular 9 项目。代码如下:

constructor(private notificationService: NotificationService) { }

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
        retry(2),
        catchError(err => {
            return throwError(this.handleError(err));
        })
    );
}

private handleError(err) {
    let errorMessage = '';
    if (err instanceof ErrorEvent) {
        errorMessage = `Error: ${err.error.message}`;
    } else if (err instanceof HttpErrorResponse) { 
        errorMessage = this.handleServerSideError(err);
    } else if (err instanceof Error) { // server side body error
        errorMessage = `Error: ${err.message}`;
    }

    if(errorMessage != "")
    {
        this.notificationService.showError(errorMessage, this.somethingWentWrong);
    }

    return errorMessage;
}

private handleServerSideError(err: HttpErrorResponse): string {
    let errorMessage = '';
    switch (err.status) {
        case 401:
            errorMessage = this.getInvalidCredentials;
            break;
        case 403:
            errorMessage = this.getNotauthorised;
            break;
        case 409:
            errorMessage = this.actionAlreadyBeingPerformed;
            break;
    }
    return errorMessage;
}

但是我写的测试不起作用。它说它是成功的,但是如果我将 expect->toEqual 更改为另一个字符串,它仍然是成功的。所以我的单元测试不起作用。我有一种感觉,我做错了什么,但我不知道是什么。我要测试的内容如下“测试失败的获取请求”。您可以在下面找到代码:

beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [ HttpClientTestingModule, ToastrModule.forRoot() ],
        providers: [ ErrorInterceptor,
            NotificationService,
            { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
          ]
    });
    
    notificationService = TestBed.inject(NotificationService);
    httpClient = TestBed.inject(HttpClient);
    httpMock = TestBed.inject(HttpTestingController);
    errorInterceptor = TestBed.inject(ErrorInterceptor);
});

it('should handle error of type Error',() => { 
    var notificationServiceSpy = spyOn(notificationService, "showError");
    
    // Make an HTTP GET request
    httpClient.get<Data>("url").subscribe(
        (error: Error) => {
            expect(error.message).toEqual("Error: the error message");
            expect(notificationServiceSpy).toHaveBeenCalledWith("Error: the error message", "Er is iets mis gegaan")
        }
    );

    // The following `expectOne()` will match the request's URL.
    const req = httpMock.expectOne("url")

    // Respond with mock error
    req.flush('', { status: 401, statusText: 'the error message' });
});

【问题讨论】:

  • req.error(new ErrorEvent('the error message'), {status: 401});
  • 我有两种错误。 Error、EventError 和 HttpErrorResponse.. 但我不能通过这些..
  • req.error(new HttpErrorResponse({error: 'the error message', status: 401})); 不起作用?
  • 它说“不能分配给类型 ErrorEvent”
  • req.error(new HttpErrorResponse({error: 'the error message', status: 401}) as any); ?

标签: angular unit-testing jasmine interceptor


【解决方案1】:
  • 首先,您需要使用error 方法而不是flush

  • 那么这是一个异步测试,所以你需要在测试完成时告诉jasmine,例如使用done函数:

    it('should handle error of type Error',(done) => { 
      var notificationServiceSpy = spyOn(notificationService, "showError");
    
      // Make an HTTP GET request
      httpClient.get<Data>("url").subscribe(() => {},
          (error: Error) => {
              expect(error.message).toEqual("Error: the error message");
              expect(notificationServiceSpy).toHaveBeenCalledWith("Error: the error message", "Er is iets mis gegaan");
             done(); // Inform jasmine that test is over
          }
      );
    
      // The following `expectOne()` will match the request's URL.
      const req = httpMock.expectOne("url")
    
      // Respond with mock error
      req.error(new HttpErrorResponse({error: 'the error message', status: 401}) as any);
    });
    

【讨论】:

  • 为什么是新的 HttpErrorResponse 而不是新的错误。 Bcs 有 Error、HttpErrorResponse 和 EventError。还是我错了?
  • 这只是匹配instance ofhandleError 方法之一的示例
  • 如果我使用这个代码:expect(error.message).toEqual("Error: thffe error message");它仍然成功..我使用了你的代码,但它应该因为“thffe”而失败..我无法解决这个问题。
  • 是否调用了(error: Error) 方法?
  • var notificationServiceSpy = spyOn(notificationService, "showError"); httpClient.get("url").subscribe( (error: Error) => { expect(error.message).toEqual("Error: thffe error message"); expect(notificationServiceSpy).toHaveBeenCalledWith("Error:错误信息", "Er is iets mis gegaan"); done(); // 通知 jasmine 测试结束 } ); const req = httpMock.expectOne("url") req.error(new Error('the error message') as any);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 2020-02-19
  • 2019-04-15
  • 2018-08-24
  • 1970-01-01
相关资源
最近更新 更多