Angular HTTP 拦截器测试失败,但拦截器工作正常

Angular HTTP Interceptor test fails while the interceptor works fine

我正在使用 karma-jasmine 为 angular-12 应用程序编写单元测试。而且,我仍然被阻止在 HTTP 拦截器测试中。这个拦截器的作用是在对服务器的任何请求的header中添加一个token。它在浏览器上运行良好,添加了令牌,我从服务器得到了响应。但是,单元测试失败,在我请求的header中没有找到授权。

下面是我的测试文件的代码,可能是什么问题,我该如何解决?

describe('JwtInterceptor', () => {
  let client: HttpClient;
  let httpTestingController: HttpTestingController;
  let interceptor: JwtInterceptor;
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
      ],
      providers: [
        JwtInterceptor,
        {
          provide: HTTP_INTERCEPTORS,
          useClass: JwtInterceptor,
          multi: true
        }
      ],
    });
    client = TestBed.inject(HttpClient)
    httpTestingController = TestBed.inject(HttpTestingController);
    interceptor = TestBed.inject(JwtInterceptor);
  });

  it('should be created', () => { /** This test succeed */
    expect(interceptor).toBeTruthy();
  });

  it('should add an Authorization header',() => { /** This is the test that fails */
    client.get('my-api-url')
          .subscribe((response)=>{
            expect(response).toBeTruthy();
          })         
    const httpRequest = httpTestingController.expectOne('my-api-url');
    expect(httpRequest.request.headers.has('Authorization')).toEqual(true);
  });
});

使用您的任何服务方法发出 http 请求。这个它可以正确验证拦截器。也不要忘记在 TestBed 配置中提供 apiUrl。

import {TestBed} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {HTTP_INTERCEPTORS, HttpClient} from '@angular/common/http';
import {API_URL, JwtInterceptor} from './jwt.interceptor';
import {DataService} from './data.service';

describe('JwtInterceptor', () => {
  let httpClient: HttpClient;
  let httpTestingController: HttpTestingController;
  let service: DataService;
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        DataService,
        {
          provide: HTTP_INTERCEPTORS,
          useClass: JwtInterceptor,
          multi: true
        },
        {
          provide: API_URL,
          useValue: {apiUrl: 'localhost'}
        }]
    });
    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);
    service = TestBed.get(DataService);
// for localstorage mocking
let store = {};
const mockLocalStorage = {
  getItem: (key: string): string => {
    return key in store ? store[key] : null;
  },
  setItem: (key: string, value: string) => {
    store[key] = `${value}`;
  },
  removeItem: (key: string) => {
    delete store[key];
  },
  clear: () => {
    store = {};
  }
};
spyOn(localStorage, 'getItem').and.callFake(mockLocalStorage.getItem);
spyOn(localStorage, 'setItem').and.callFake(mockLocalStorage.setItem);
spyOn(localStorage, 'removeItem').and.callFake(mockLocalStorage.removeItem);
spyOn(localStorage, 'clear').and.callFake(mockLocalStorage.clear);
});



  afterEach(() => {
    httpTestingController.verify();
  });



  describe('making http calls', () => {
    it('adds authorization header', () => {
      const apiUrl = TestBed.get(API_URL);
      service.getData().subscribe(response => {
        expect(response).toBeTruthy();
      });

  localStorage.setItem('auth_token', 'any auth token here');
  const authToken = localStorage.getItem('auth_token');
  const req = httpTestingController.expectOne(apiUrl + '/getData');
  expect(req.request.headers.has('Authorization')).toEqual(true);
  expect(req.request.headers.get('Authorization')).toEqual(`Bearer ${authToken}`);
  });
 });

});