我有一个下面的拦截器auth-interceptor.service.ts
import {Injectable,Injector} from '@angular/core'; import {HttpErrorResponse,HttpEvent,HttpHandler,HttpInterceptor,HttpRequest} from '@angular/common/http'; import {Observable} from 'rxjs/Observable'; import {Cookie} from './cookie.service'; import {Router} from '@angular/router'; import {UserService} from './user.service'; import {ToasterService} from '../toaster/toaster.service'; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private injector: Injector) {} private handleError(err: HttpErrorResponse): Observable<any> { let errorMsg; if (err.error instanceof Error) { // A client-side or network error occurred. Handle it accordingly. errorMsg = `An error occurred: ${err.error.message}`; } else { // The backend returned an unsuccessful response code. // The response body may contain clues as to what went wrong,errorMsg = `Backend returned code ${err.status},body was: ${err.error}`; } if (err.status === 401 || err.status === 403) { this.injector.get(UserService).purgeAuth(); this.injector.get(ToasterService).showError(`Unauthorized`,errorMsg); this.injector.get(Router).navigateByUrl(`/login`); } console.error(errorMsg); return Observable.throw(errorMsg); } intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> { // Clone the request to add the new header. const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey,Cookie.getToken())}); // Pass on the cloned request instead of the original request. return next.handle(authReq).catch(err => this.handleError(err)); } }
现在我试图模拟http.get来抛出错误,因此方法handleError控制错误消息.
下面是我对测试用例auth-interceptor.service.specs.ts的方法
import {async,inject,TestBed} from '@angular/core/testing'; import {AuthInterceptor} from './auth-interceptor.service'; import {ApiService} from './api.service'; import {HttpClientTestingModule,HttpTestingController} from '@angular/common/http/testing'; import {environment} from '../../../environments/environment'; describe(`AuthInterceptor`,() => { const somePath = `/somePath`; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule],providers: [AuthInterceptor,ApiService] }); }); it(`should be created`,inject([AuthInterceptor],(service: AuthInterceptor) => { expect(service).toBeTruthy(); })); it(`should log an error to the console on error on get()`,async(inject([ApiService,HttpTestingController],(apiService: ApiService,httpMock: HttpTestingController) => { spyOn(console,'error'); apiService.get(somePath).subscribe((res) => { console.log(`in success:`,res); },(error) => { console.log(`in error:`,error); }); const req = httpMock.expectOne(`${environment.apiUri}${somePath}`); req.flush({ type: 'ERROR',status: 404,body: JSON.stringify({color: `blue`}) }); expect(console.error).toHaveBeenCalled(); })) ); });
在刷新响应时,我不确定如何刷新错误响应,以便在我的拦截器中调用方法handleError,最终调用console.error.文档没有我的情况的任何例子.任何帮助或建议表示赞赏.
HttpTestingController类中的expectOne方法返回一个TestRequest对象.此TestRequest类具有可用于传递的flush方法
原文链接:https://www.f2er.com/angularjs/140456.htmlboth successful and unsuccessful responses.
我们可以通过返回一个正文以及一些额外的响应头(如果有的话)来解决请求.相关信息可以在here找到.
现在,回过头来说明如何做到这一点.您可以根据您的使用情况自定义以下代码段.
http = TestBed.get(HttpTestingController); let response:any; let errResponse: any; const mockErrorResponse = { status: 404,statusText: 'Bad Request' }; const data = 'Invalid request parameters'; apiService.get(somePath).subscribe(res => response=res,err => errResponse=err); http.expectOne('url/being/monitored').flush(data,mockErrorResponse); expect(errResponse).toBe(data);
注意:在撰写此注释时,mockErrorResponse中需要statusText.相关信息可以在here找到.
P.S.:TestRequest类的错误方法可用于在我们的测试用例中模拟网络错误,因为它需要一个Error实例.以下代码段显示了这一点.
http.expectOne(someUrl).error(new ErrorEvent('network error'));