簡體   English   中英

Angular 13 TestBed 不注入攔截器

[英]Angular 13 TestBed doesn't inject interceptor

我有一個帶有自定義 HTTP 客戶端和攔截器的 Angular 13 應用程序,我想對其進行單元測試。

base-url.interceptor.ts

import { Inject, Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';

export const BASE_API_URL = 'BASE_API_URL';

@Injectable()
export class BaseUrlInterceptor implements HttpInterceptor {
  constructor(@Inject(BASE_API_URL) private baseUrl: string) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const apiRequest = request.clone({ url: `${this.baseUrl}${request.url}` });
    return next.handle(apiRequest);
  }
}

base-url.interceptor.spec.ts

import { TestBed } from '@angular/core/testing';
import { ApiHttpService, API_HTTP_INTERCEPTORS } from '../api-http.service';
import { BaseUrlInterceptor, BASE_API_URL } from './base-url.interceptor';

describe('BaseUrlInterceptor', () => {
  let interceptor: BaseUrlInterceptor;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [],
      providers: [
        ApiHttpService,
        { provide: BASE_API_URL, value: 'http://example.com' },
        { provide: API_HTTP_INTERCEPTORS, useClass: BaseUrlInterceptor, multi: true }
      ]
    });
    interceptor = TestBed.inject(BaseUrlInterceptor);
  });

  it('should be created', () => {
    expect(interceptor).toBeTruthy();
  });
});

不幸的是TestBed.inject(BaseUrlInterceptor)未能注入攔截器的實例。 interceptor器總是undefined 如果我通過手動創建實例來解決這個問題new BaseUrlInterceptor('http://example.com'); 它有效,但其他攔截器有進一步的依賴關系,我想在這里使用 Angulars 依賴注入。

我如何配置 TestBed,以便它可以成功創建BaseUrlInterceptor的實例?

我創建了一個重現問題的最小 CodeSandbox: https://codesandbox.io/s/snowy-dust-t964no?file=/src/app/base-url.interceptor.spec.ts

測試沙盒

此外,當我運行錯誤測試時,我收到此錯誤消息:

Chrome Headless 98.0.4758.102 (Linux x86_64) BaseUrlInterceptor should be created FAILED
        Error: NG0204: unreachable
        error properties: Object({ code: 204 })
        Error: NG0204: unreachable
            at injectableDefOrInjectorDefFactory (node_modules/@angular/core/fesm2015/core.mjs:11494:1)
            at providerToFactory (node_modules/@angular/core/fesm2015/core.mjs:11556:1)
            at providerToRecord (node_modules/@angular/core/fesm2015/core.mjs:11521:1)
            at R3Injector.processProvider (node_modules/@angular/core/fesm2015/core.mjs:11424:1)
            at node_modules/@angular/core/fesm2015/core.mjs:11410:1
            at node_modules/@angular/core/fesm2015/core.mjs:4162:1
            at Array.forEach (<anonymous>)
            at deepForEach (node_modules/@angular/core/fesm2015/core.mjs:4162:1)
            at R3Injector.processInjectorType (node_modules/@angular/core/fesm2015/core.mjs:11410:1)
            at node_modules/@angular/core/fesm2015/core.mjs:11213:1
        Error: Expected undefined to be truthy.
            at <Jasmine>
            at UserContext.<anonymous> (projects/frontend/src/app/core/http/interceptors/base-url.interceptor.spec.ts:21:25)
            at ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
            at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
Chrome Headless 98.0.4758.102 (Linux x86_64): Executed 1 of 1 (1 FAILED) (0.072 secs / 0.056 secs)
TOTAL: 1 FAILED, 0 SUCCESS

您收到Error: NG0204: unreachable是因為當您為BASE_API_URL定義提供程序時,您使用的是屬性value ,而它應該是useValue

{ provide: BASE_API_URL, useValue: 'http://example.com' },

無論如何,即使你修復了它,你也會得到一個NullInjectorError ,因為你沒有定義一個使用BaseUrlInterceptor class 作為 InjectionToken 的提供者。 您正在使用 class 作為API_HTTP_INTERCEPTORS令牌的提供者之一。

在對攔截器進行單元測試的上下文中,您應該擺脫 ApiHttpService,而只關注攔截器 class。

你有兩個選擇:

手動實例化 class

beforeEach(() => {
    interceptor = new BaseUrlInterceptor('http://example.com');
});

或者在 Testbed 中使用攔截器 class 作為提供者

beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [],
      providers: [
        { provide: BASE_API_URL, useValue: 'http://example.com' },
        BaseUrlInterceptor,
      ],
    });
    interceptor = TestBed.inject(BaseUrlInterceptor);
  });

干杯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM