[英]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.