【问题标题】:How to write Test Case for Interceptor in Angular如何在 Angular 中为拦截器编写测试用例
【发布时间】:2020-02-04 13:57:36
【问题描述】:

我正在尝试测试 Angular 6 提供的 HttpInterceptor。我根据示例创建了一个拦截器,但我无法为下面的拦截器编写测试用例,请指导我完成以下问题

拦截器

@Injectable()
export class AutherizationInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (req.headers.has(InterceptorSkipHeader)) {
      const headers = req.headers.delete(InterceptorSkipHeader);
      return next.handle(req.clone({ headers }));
    } else {
      const modified = req.clone({
        setHeaders:
        {
          'Authorization': localStorage.getItem(GlobalVariables.AUTHERIZATION_TOEKN),
          'Content-Type': 'application/json'
        }
      });
      return next.handle(modified);
    }
  }
}

测试

describe('Lang-interceptor.service', () => {

let httpMock: HttpTestingController;
let interceptor: AutherizationInterceptor;
beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [HttpClientModule, HttpClientTestingModule],
        providers: [{
            provide: HTTP_INTERCEPTORS,
            useClass: AutherizationInterceptor,
            multi: true
        }]
    })
    httpMock = TestBed.get(HttpTestingController);
    interceptor = new AutherizationInterceptor();
});

it('should include a Content-Type header', inject([HttpClient], (http: HttpClient) => {
    const httpOptions = {
      headers: new HttpHeaders({'Content-Type': 'application/json'})
    }
    http.post(environment.baseUrl + 'api/user/login',null, httpOptions).subscribe();
    const httpRequest = httpMock.expectOne(environment.baseUrl + 'api/user/login');
    httpRequest.request.headers.delete(InterceptorSkipHeader);
    expect(httpRequest.request.headers.has('Content-Type')).toBe(true);
    expect(httpRequest.request.headers.get('Content-Type')).toBe('application/json');

    httpMock.verify();
  }));

错误

Chrome 75.0.3770 (Windows 10.0.0) Lang-interceptor.service should include a Content-Type header FAILED
    TypeError: Cannot read property 'length' of null
        at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.applyUpdate node_modules/@angular/common/fesm5/http.js:200:1)
        at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/common/fesm5/http.js:171:60
        at Array.forEach (<anonymous>)

【问题讨论】:

  • 我这两天遇到这个问题,请指导我

标签: angular typescript unit-testing karma-jasmine


【解决方案1】:

您的测试是正确的,因为您没有调用在您期望之前进行 http 调用的服务。

您还可以通过直接 http 调用来扩展您的测试,它应该会变成绿色。

...
  it('should include a Content-Type header', inject([HttpClient], (http: HttpClient) => {

    const httpOptions = {
      headers: new HttpHeaders({'Content-Type': 'application/json'})
    }

    http.get(environment.baseUrl + 'api/user/login', httpOptions).subscribe();

    const httpRequest = httpMock.expectOne(environment.baseUrl + 'api/user/login');
     // httpRequest.request.headers.delete(InterceptorSkipHeader);

    expect(httpRequest.request.headers.has('Content-Type')).toBe(true);
    expect(httpRequest.request.headers.get('Content-Type')).toBe('application/json');

    httpMock.verify();
  }));
...

【讨论】:

  • Lang-interceptor.service 拦截 HTTP 请求应包含 Content-Type 标头 FAILED TypeError: Cannot read property 'length' of null
  • @Krish 你是对的,我忘了添加内容类型。检查我编辑的答案。
  • 让我检查并告诉结果
  • 我仍然面临问题,我用错误消息更新我的问题
  • 嗯,你能取消注释httpRequest.request.headers.delete(InterceptorSkipHeader); 的行吗?这是我在本地测试中唯一没有的。
猜你喜欢
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多