簡體   English   中英

在 Angular 和 JEST 的單元測試中沒有 @Inject('environment') 的提供者

[英]No provider for @Inject('environment') in Unit Test with Angular & JEST

我有一個問題,如何測試我們在 Angular 應用程序(版本 13)中編寫的服務之一。

這是我要測試的服務(AdressService)的一部分:

@Injectable({
  providedIn: 'root'
})
export class AddressService {
  private formDataSource = new BehaviorSubject<ICreateEditAddress>({
    id: null,
    company: null,
    lastName: null,
    firstName: null,
    street: null,
    streetNumber: null,
    zip: null,
    city: null,
    country: null,
    countryOptions: null,
    formFields: null
  });
  public readonly formData = this.formDataSource.asObservable();

  constructor(
    @Inject(LOCALE_ID) private language: string,
    private graphQlService: GraphQLService,
  ) {
  }
  public async getAddressDetailsForm(id?: string | number): Promise<ICreateEditAddress> {
    return this.graphQlService.performStandardQuery<IGetAddressDetailsResponse>({
      query: createEditAddressQuery,
      queryVariables: {
        lang: this.language,
        id: id || null,
      },
      relatedObservable: this.addressGetDetailsObservable,
    }).then(result => {
      if (typeof result?.data?.address === 'object') {
        this.formDataSource.next({
          ...this.filterAddressDetailsResponse(result.data.address)
        });
      }
      return result?.data?.address;
    });
  }
}

在 GraphQLService 里面我有:

@Injectable({
  providedIn: 'root'
})
export class GraphQLService {
  constructor(
    @Inject(LOCALE_ID) protected language: string,
    protected apollo: Apollo,
    protected error: ErrorService,
    private router: Router,
    private browser: BrowserService,
  ) {
  }
}

最后在 ErrorService 我有:

@Injectable({
  providedIn: 'root'
})
export class ErrorService {
  private messageSubject = new Subject<IErrorEvent>();
  public readonly message = this.messageSubject.asObservable();
  private readonly renderer: Renderer2;

  constructor(
    @Inject('environment') public environment: any,
    private browser: BrowserService,
    rendererFactory: RendererFactory2,
  ) {
    this.renderer = rendererFactory.createRenderer(null, null);
  }
}

我的測試用例如下所示:

describe('Address service', () => {
  let service: AddressService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      // imports: [AppModule], { provide: APP_BASE_HREF, useValue: '/'} - not working, generating error NotSupportedError: This name has already been registered in the registry.
      providers: [AddressService, GraphQLService, Apollo, ErrorService, Router, BrowserService], //
      // providers: [AddressService, GraphQLService, Apollo, ErrorService, Router, BrowserService] -> not working missing declaration for environment which is  @Inject('environment') public environment: any in ErrorService. This is file with configuration, one const which is exported.
      // Error: NullInjectorError: R3InjectorError(DynamicTestModule)[AddressService -> GraphQLService -> ErrorService -> environment -> environment]: 
      // NullInjectorError: No provider for environment!
    });
    service = TestBed.inject(AddressService);
  });

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

  it('should return an empty address', async () => {
    await service.getAddressDetailsForm('1');
    await service.getAddressDetailsForm();
    const form = service.getFormData();
    expect(form.city).toBeNull();
  });
});

我嘗試了幾種使用 @Inject('environment') -> 來解決問題的方法。 當我添加上面示例中的服務時,出現如下錯誤:

NullInjectorError: R3InjectorError(DynamicTestModule)[AddressService -> GraphQLService -> ErrorService -> environment -> environment]: 
      NullInjectorError: No provider for environment!

當我刪除所有提供者但只保留providers: [AddressServices]並添加imports: [AppModule] ,我收到此錯誤:

NotSupportedError: This name has already been registered in the registry.

你能幫我解決這個問題嗎?

您不應該導入AppModule 在單元測試中,您只需導入/提供您正在測試的單個類/元素,並模擬它可能具有的任何依賴項。

在這種情況下,您將提供AddressService以及LOCALE_ID的值和GraphQLService的模擬。 而已。

暫無
暫無

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

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