单元测试Angular 4中的HttpInterceptor

时间:2017-09-14 17:30:53

标签: angular

你能告诉我如何测试Angular 4提供的HttpInterceptor。我已根据示例创建了一个拦截器,但不知道如何测试它。下面是我的拦截器,我想测试是否添加了自定义标头,以及响应状态是401 Scan

window.location.href

5 个答案:

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

我还使用了服务模拟程序,该服务模拟程序生成令牌来控制我想要验证的值。