所以我试图在不使用测试平台的情况下对我的拦截器进行单元测试。拦截器只是将不记名令牌附加到 Auth 标头。我似乎无法弄清楚如何实际检查是否已附加这些标头。当订阅返回可观察的 next.handle() 的拦截器时,我没有得到任何响应,而且订阅块中的所有代码都不会执行。我使用的是 Angular 版本 15.2.2、Jest 28.1.3 和 RxJs 7.5.6。

拦截器

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authService.isLoggedIn()) {
  return this.authService.acquireToken().pipe(
    switchMap((data: any) => {
      if (data !== null) {
        let updatedRequest: HttpRequest<any>;
        const authToken = data.accessToken;
        updatedRequest = request.clone({
          setHeaders: {
            Authorization: `Bearer ${authToken}`,
          },
        });
        updatedRequest.headers.append('Authorization', `Bearer ${authToken}`);
        return next.handle(updatedRequest);
      }
    })
  );
} else {
  return EMPTY;
}

单元测试

it('[Intercept] Should intercept the API requests and append auth token if user logged in', (done: DoneCallback) => {
const next: any = {
  handle: () => {
    return Observable.create((subscriber) => {
      subscriber.complete();
    });
  },
};
const requestMock = new HttpRequest('GET', '/test');
const y = interceptor.intercept(requestMock, next).pipe(
  map((r) => r),
  catchError(() => throwError('err')),
  take(1),
  finalize(() => {
    done();
  })
);
y.subscribe((i) => {
  console.log('API call intercepted'), console.log(requestMock.headers);
});

});

任何帮助将不胜感激,因为我完全迷路了!谢谢大家。


 updatedRequest.headers.append('Authorization', `Bearer ${authToken}`);

这一行不会修改updatedRequest.headers而是会创建新的 HttpHeaders 实例

subscribe 中的代码没有被执行,因为 Observable 从不发射任何值,它只是立即完成。

这就是我在我的应用程序中测试类似拦截器的方式:

it('should add authorization header', () => {

    // interceptor depends on AuthStateService
    authStateService.setState({
      token: 'fake-token'
    })

    const next: HttpHandler = {
      handle: () => {
        return new Observable((subscriber: Subscriber<any>) => {
          subscriber.complete();
        });
      }
    };
    const requestMock = new HttpRequest('GET', '/test');

    spyOn(next, 'handle').and.callThrough();

    tokenInterceptor.intercept(requestMock, next).subscribe();

    expect(next.handle).toHaveBeenCalledWith(requestMock.clone({
      headers: requestMock.headers.append('Authorization', `Bearer fake-token`)
    }))

  });

感谢@displayName。这正是答案,现在就像一个魅力。问题中不包括:mockAuthenticationService = { isLoggedIn: () => true, acquireToken: () => of({ accessToken: 'lewis' }), }; 所以不太确定,尝试在您的代码中记录响应也没有用。感谢您指出我在标题方面的错误,这让学习变得更加愉快!将此标记为决议,干杯。

@LewisMorgans 我认为 subscribe 中的代码不会被执行,因为 Observable 从不发出任何值。它立即完成。如果你在它应该被执行subscriber.next(someValue)之前添加。subscriber.complete()但是,如果您这样写,对于测试来说并不是很重要。