Angular 单元测试 HTTP 请求标头

Posted

技术标签:

【中文标题】Angular 单元测试 HTTP 请求标头【英文标题】:Angular unit test HTTP request header 【发布时间】:2021-12-19 12:28:21 【问题描述】:

我想编写一个单元测试来检查 http 请求的标头。但是,当我尝试访问请求标头时,测试总是以错误结束:

it('should have my header', () =>     
  httpClient.get('/someURL').subscribe();
  const req = httpTestingController.match( method: 'get' );
  console.log(req[0].request.headers);   
  expect(req[0].request.headers.has('Custom-Header')).toEqual(true);
  httpTestingController.verify();
);

单元测试失败并出现以下错误:

TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.

我尝试了各种方法,但我总是在访问标题的“预期”行中收到此错误。当我在控制台中记录标题时,它看起来像这样:

LOG: HttpHeadersnormalizedNames: Map, lazyUpdate: [Objectname: ..., value: ..., op: ...], headers: Map, lazyInit: HttpHeadersnormalizedNames: Map, lazyUpdate: null, headers: Map

【问题讨论】:

【参考方案1】:

您的规范中是否还有其他使用扩展运算符的代码?

请参阅下面的工作示例。

import  HttpClient, HttpClientModule, HttpHeaders, HttpRequest  from '@angular/common/http';
import 
  HttpClientTestingModule,
  HttpTestingController,
  TestRequest,
 from '@angular/common/http/testing';
import  TestBed, waitForAsync  from '@angular/core/testing';

describe('headers test', () => 
  let httpTestingController: HttpTestingController;
  let httpClient: HttpClient;

  beforeEach(
    waitForAsync(() => 
      void TestBed.configureTestingModule(
        imports: [HttpClientTestingModule, HttpClientModule],
      )
        .compileComponents()
        .then(() => 
          httpTestingController = TestBed.inject(HttpTestingController);
          httpClient = TestBed.inject(HttpClient);
        );
    ),
  );

  afterEach(() => 
    httpTestingController
      .match((req: HttpRequest<unknown>): boolean => true)
      .forEach((req: TestRequest) => (!req.cancelled ? req.flush() : null));
    httpTestingController.verify();
  );

  it('should have my header', () => 
    const headers = new HttpHeaders().set('Custom-Header', 'test');
    void httpClient.get('/someURL',  headers ).subscribe();
    const req = httpTestingController.match('/someURL');
    console.warn('req', req);
    console.warn(req[0].request.headers);
    expect(req[0].request.headers.has('Custom-Header')).toEqual(true);
  );
);

【讨论】:

您的代码也可以正常工作。但我的也是。问题是我在测试中使用的一个模拟类。

以上是关于Angular 单元测试 HTTP 请求标头的主要内容,如果未能解决你的问题,请参考以下文章

单元测试 Angular 12 HTTP 拦截器 expectOne 失败

Angular中的单元测试

用于单元测试 .NET 核心 MVC 控制器的模拟 HttpContext?

使用 jasmine / karma 进行 Angular 4 单元测试和 http post mocking - 如何修复

如何向使用 Selenium Webdriver 处理的 HTTP 请求添加标头或参数?

Angular 2 JWT 单元测试