簡體   English   中英

單元測試Angular 4中的HttpInterceptor

[英]Unit testing HttpInterceptor from Angular 4

你能告訴我如何測試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);
            });
    }

我被困在測試類似的東西,但感謝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();
        }));
    });

我有點遲到了,但我想出了一種在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();
});

瞧!

只需進行任何調用並使用HttpTestingController .error()方法模擬響應,它應該可以工作。

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();
  });

});

攔截器測試類似於測試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');
        }));
    });

模擬您的服務將為您提供在測試期間要復制的數據。

我想從攔截器修改的請求中獲取響應,因此我使用了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);
}));

我還使用了一個服務模擬器來生成令牌來控制我想要驗證的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM