单元测试Angular 4中的HttpInterceptor

Ang*_*gad 18 angular

你能告诉我如何测试Angular 4提供的HttpInterceptor.我根据例子创建了一个拦截器,但不知道如何测试它.下面是我的拦截器,我想测试是否添加了自定义标头以及何时完成响应状态为401 window.location.href.

export class MyInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const headers = new HttpHeaders();
        this.addHeader(headers); // This will add headers

        const changedReq = req.clone({ headers: headers });
        return next.handle(req)
            .catch(err => {
                if (err instanceof HttpErrorResponse) {
                    switch (err.status) {
                        case 302:
                        case 401:
                            window.location.href = "http//google.com";
                            break;             
                        default:
                            throw new Error(this.getErrorMessage(err));
                    }
                }

                return Observable.throw(err);
            });
    }
Run Code Online (Sandbox Code Playgroud)

ram*_*n22 28

我被困在测试类似的东西,但感谢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();
        }));
    });
Run Code Online (Sandbox Code Playgroud)


小智 8

我有点迟到了,但我想出了一种在Angular的背景之外测试拦截器的方法.这意味着您不必模拟HTTP调用,只需intercept像任何Javascript函数一样测试函数.

假设您的拦截器只执行该操作,如果错误状态为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'); }
    });
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的服务中,您可以模拟您的函数的参数,如下所示:

const err: any = { status: 500 };
const next: any = {
  handle: (request: HttpRequest<any>) => ({
    catch: (callback: Function) => callback(err)
  })
};
Run Code Online (Sandbox Code Playgroud)

有了它,你可以为你的拦截器编写一个测试:

it('should write a console log with error status equal to 500', () => {
  spyOn(console, 'log');

  service.intercept({} as any, next);

  expect(console.log).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

瞧!

  • 取决于您对单元测试的概念.对我来说,拦截器的拦截方法应该做某事(在这种情况下,日志).因此,您可以在Angular的上下文之外对其进行单元测试.例如,如果你想测试一下,标题会附加到你的请求中,你可以先测试一下这个孤立的测试确实附加了标题,并测试你的服务所做的请求是否带有正确的标题. (4认同)

小智 5

我想从拦截器修改的请求中获取响应,所以我使用了句柄对象的回调方法。

测试:

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

我还使用了一个服务模拟来生成令牌来控制我想要验证的值。


Ani*_*Das 2

拦截器测试类似于 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');
        }));
    });
Run Code Online (Sandbox Code Playgroud)

模拟您的服务将为您提供您想要在测试期间复制的数据。