2017-09-14 57 views
6

你能告訴我如何測試Angular 4提供的HttpInterceptor。我已經根據示例創建了一個攔截器,但不知道如何測試它。下面是我的攔截器,我想測試自定義頭文件是否被添加,當響應狀態是401 window.location.href完成。單元測試來自Angular 4的HttpInterceptor

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

回答

0

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

嘲笑你的服務會給你想要在測試過程中複製的數據。

+0

謝謝,但我不明白你在這種情況下你的模型。我想做一個http.get調用,並且想要檢查攔截器是否添加了頭部並且想要模擬響應。 – Angad

+0

你可以跳過。如果你不嘲笑任何東西,它不是必需的。 –

10

我被困測試了類似的事情,但由於阿利薩的文章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(); 
    })); 
}); 
0

只是做任何電話和模擬用的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(); 
    }); 

}); 
1

我有點晚了職位,但我想通了測試攔截角的範圍內的之外的一種方式。這意味着你不需要模擬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(); 
}); 

,瞧!