你能告诉我如何测试Angular 4提供的HttpInterceptor。我已根据示例创建了一个拦截器,但不知道如何测试它。下面是我的拦截器,我想测试是否添加了自定义标头,以及响应状态是401 Scan
。
window.location.href
答案 0 :(得分:22)
我被困在测试类似的东西,但感谢Alisa的文章Intercepting Http Requests我得到了它的工作
import {TestBed, inject} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {HTTP_INTERCEPTORS, HttpClient} from '@angular/common/http';
import {LangInterceptorService} from './lang-interceptor.service';
describe('Lang-interceptor.service', () => {
beforeEach(() => TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: LangInterceptorService,
multi: true
}]
}));
describe('intercept HTTP requests', () => {
it('should add Accept-Language to Headers', inject([HttpClient, HttpTestingController],
(http: HttpClient, mock: HttpTestingController) => {
http.get('/api').subscribe(response => expect(response).toBeTruthy());
const request = mock.expectOne(req => (req.headers.has('Accept-Language') && req.headers.get('Accept-Language') === 'ar'));
request.flush({data: 'test'});
mock.verify();
}));
});
afterEach(inject([HttpTestingController], (mock: HttpTestingController) => {
mock.verify();
}));
});
答案 1 :(得分:6)
我有点迟到了,但我想出了一种测试Angular上下文之外的拦截器的方法。这意味着您不必模拟HTTP调用,只需像任何Javascript函数一样测试intercept
函数。
假设您的拦截器只执行此操作,如果错误状态为500,则显示日志:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(req)
.catch((err: HttpErrorResponse) => {
if(err.status === 500) { console.log('Server error'); }
});
}
然后,在您的服务中,您可以像这样模拟函数的参数:
const err: any = { status: 500 };
const next: any = {
handle: (request: HttpRequest<any>) => ({
catch: (callback: Function) => callback(err)
})
};
有了这个,你可以为你的拦截器写一个测试:
it('should write a console log with error status equal to 500', () => {
spyOn(console, 'log');
service.intercept({} as any, next);
expect(console.log).toHaveBeenCalled();
});
瞧!
答案 2 :(得分:3)
使用.error()
HttpTestingController
方法进行任何调用并模拟回复,它应该有效。
describe('Error interceptor', function () {
let http: HttpTestingController;
let httpClient: HttpClient;
beforeEach(() => {
const testBed = TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MyInterceptor,
multi: true
}
],
});
http = testBed.get(HttpTestingController);
httpClient = testBed.get(HttpClient);
});
it('should catch 401', function (done) {
httpClient.get('/error').subscribe(() => {}, () => {
// Perform test
done();
});
http.expectOne('/error').error(new ErrorEvent('Unauthorized error'), {
status: 401
});
http.verify();
});
});
答案 3 :(得分:1)
拦截器测试类似于测试Angular服务。 TestBed将提供测试它们所需的一切。
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MyInterceptor,
multi: true
}]
});
});
describe('making http calls', () => {
it('adding header test', inject([HttpClient, YourMock], (http: HttpClient, httpMock: YourMock) => {
http.get('/data').subscribe(
response => {
expect(response).toBeTruthy();
}
);
expect(response.status).toEqual('401');
}));
});
模拟您的服务将为您提供测试期间要复制的数据。
答案 4 :(得分:1)
我想从拦截器修改后的请求中获取响应,因此我使用了handle对象的回调方法。
测试:
it("should set header authorization", async(() => {
const token: string = "token_value";
let response: HttpResponse<any>;
const next: any = {
handle: responseHandle => {
response = responseHandle;
}
};
const request: HttpRequest<any> = new HttpRequest<any>("GET", `${API_URL}`);
tokenInterceptor.intercept(request, next);
expect(response.headers.get("Authorization")).toEqual(token);
}));
我还使用了服务模拟程序,该服务模拟程序生成令牌来控制我想要验证的值。