Angular 13 如何对拦截器的catchError方法进行单元测试
Angular 13 How to Unit Test Interceptor catchError method
我正在处理一个现有的 Angular 项目,我有以下带有错误处理的拦截器。
这是代码:
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const sendAccessToken = this.moduleConfig.resourceServer.sendAccessToken;
if (sendAccessToken) {
const token = this.authStorage.getItem('access_token');
const header = 'Bearer ' + token;
const headers = req.headers.set('Authorization', header);
req = req.clone({ headers });
}
return next.handle(req).pipe(
catchError(err => {
let errorMessage: string;
if (err instanceof HttpErrorResponse) {
switch (err.status) {
case 401: {
errorMessage = 'Autorisation required.';
break;
}
default: {
const erreurText = err.error.messages[0].message
break;
}
}
}
this.toastr.error(errorMessage);
const error = err.error;
return error;
}),
) as any;
}
这是我的测试,我想在其中触发捕手错误,但我不知道该怎么做:
it('#should handle incorrect url', () => {
const requestMock = new HttpRequest('GET', '/wrongtest');
interceptor.intercept(requestMock, next).subscribe(() => {
expect(requestMock.headers.has('Authorization')).toEqual(false);
});
});
任何人都可以指导我如何触发我的 HttpRequest 中的错误。
提前致谢。
假设您使用 jasmine 进行测试:
- 注入所有测试依赖项:
// Necessary to inject the right HTTP interceptor
const interceptorOf = <T>(type: Type<T>) =>
TestBed
.inject(HTTP_INTERCEPTORS)
.find(interceptor => interceptor instanceof type) as unknown as T
describe('...', () => {
let httpClient: HttpClient
let httpMock: HttpTestingController
let interceptor: ErrorInterceptor
beforeEach(async () =>
await TestBed.configureTestingModule({
imports: [
// Load all your interceptor's dependencies
HttpClientTestingModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
deps: [], // Fill with your interceptor's dependencies
useClass: ErrorInterceptor,
multi: true
},
],
}).compileComponents()
httpMock = TestBed.inject(HttpTestingController)
httpClient = TestBed.inject(HttpClient)
interceptor = interceptorOf(ErrorInterceptor)
})
})
- 调用普通端点并模拟响应:
it('should do something', async () =>{
const observable$ = httpClient.get(testUrl)
const serviceUnavailable = new HttpErrorResponse({
status: 503,
statusText: 'Service Unavailable',
url: testUrl
})
const httpReqPromise = firstValueFrom(observable$)
httpMock.expectOne(testUrl).flush('error', serviceUnavailable)
try {
await httpReqPromise
fail('It should have not succeeded')
} catch(error) {
expect(error instanceof HttpErrorResponse).toBeTrue()
expect(error.status).toBe(503)
}
})
注1:您的catchError
管道用法无效;你不应该 return 一个错误,而是一个将被用来代替崩溃的可观察对象。
catchError(err => {
...
const error = err.error;
return of(error);
})
注意 2:如果您像我在上面的代码片段中所做的那样,您的错误将传播到“下一个”回调中,该回调应该将以下承诺解析为成功
it('should do something', async () =>{
const observable$ = httpClient.get(testUrl)
const serviceUnavailable = new HttpErrorResponse({
status: 503,
statusText: 'Service Unavailable',
url: testUrl
})
const httpReqPromise = firstValueFrom(observable$)
httpMock.expectOne(testUrl).flush('error', serviceUnavailable)
try {
const error = await httpReqPromise
expect(error instanceof HttpErrorResponse).toBeTrue()
expect(error.status).toBe(503)
} catch(__) {
fail('It should have not thrown')
}
})
我正在处理一个现有的 Angular 项目,我有以下带有错误处理的拦截器。 这是代码:
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const sendAccessToken = this.moduleConfig.resourceServer.sendAccessToken;
if (sendAccessToken) {
const token = this.authStorage.getItem('access_token');
const header = 'Bearer ' + token;
const headers = req.headers.set('Authorization', header);
req = req.clone({ headers });
}
return next.handle(req).pipe(
catchError(err => {
let errorMessage: string;
if (err instanceof HttpErrorResponse) {
switch (err.status) {
case 401: {
errorMessage = 'Autorisation required.';
break;
}
default: {
const erreurText = err.error.messages[0].message
break;
}
}
}
this.toastr.error(errorMessage);
const error = err.error;
return error;
}),
) as any;
}
这是我的测试,我想在其中触发捕手错误,但我不知道该怎么做:
it('#should handle incorrect url', () => {
const requestMock = new HttpRequest('GET', '/wrongtest');
interceptor.intercept(requestMock, next).subscribe(() => {
expect(requestMock.headers.has('Authorization')).toEqual(false);
});
});
任何人都可以指导我如何触发我的 HttpRequest 中的错误。
提前致谢。
假设您使用 jasmine 进行测试:
- 注入所有测试依赖项:
// Necessary to inject the right HTTP interceptor
const interceptorOf = <T>(type: Type<T>) =>
TestBed
.inject(HTTP_INTERCEPTORS)
.find(interceptor => interceptor instanceof type) as unknown as T
describe('...', () => {
let httpClient: HttpClient
let httpMock: HttpTestingController
let interceptor: ErrorInterceptor
beforeEach(async () =>
await TestBed.configureTestingModule({
imports: [
// Load all your interceptor's dependencies
HttpClientTestingModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
deps: [], // Fill with your interceptor's dependencies
useClass: ErrorInterceptor,
multi: true
},
],
}).compileComponents()
httpMock = TestBed.inject(HttpTestingController)
httpClient = TestBed.inject(HttpClient)
interceptor = interceptorOf(ErrorInterceptor)
})
})
- 调用普通端点并模拟响应:
it('should do something', async () =>{
const observable$ = httpClient.get(testUrl)
const serviceUnavailable = new HttpErrorResponse({
status: 503,
statusText: 'Service Unavailable',
url: testUrl
})
const httpReqPromise = firstValueFrom(observable$)
httpMock.expectOne(testUrl).flush('error', serviceUnavailable)
try {
await httpReqPromise
fail('It should have not succeeded')
} catch(error) {
expect(error instanceof HttpErrorResponse).toBeTrue()
expect(error.status).toBe(503)
}
})
注1:您的catchError
管道用法无效;你不应该 return 一个错误,而是一个将被用来代替崩溃的可观察对象。
catchError(err => {
...
const error = err.error;
return of(error);
})
注意 2:如果您像我在上面的代码片段中所做的那样,您的错误将传播到“下一个”回调中,该回调应该将以下承诺解析为成功
it('should do something', async () =>{
const observable$ = httpClient.get(testUrl)
const serviceUnavailable = new HttpErrorResponse({
status: 503,
statusText: 'Service Unavailable',
url: testUrl
})
const httpReqPromise = firstValueFrom(observable$)
httpMock.expectOne(testUrl).flush('error', serviceUnavailable)
try {
const error = await httpReqPromise
expect(error instanceof HttpErrorResponse).toBeTrue()
expect(error.status).toBe(503)
} catch(__) {
fail('It should have not thrown')
}
})