I have a problem how to test one of our services writing in angular app (version 13).
This is part of the service (AdressService) which I want to test:
@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;
});
}
}
Inside GraphQLService I have:
@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,
) {
}
}
Finally in ErrorService I have:
@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);
}
}
My test case look like:
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();
});
});
I try on several way to use @Inject('environment') -> to solve problem. When I adding services like in example above I got error like:
NullInjectorError: R3InjectorError(DynamicTestModule)[AddressService -> GraphQLService -> ErrorService -> environment -> environment]:
NullInjectorError: No provider for environment!
When I remove all providers but keep only providers: [AddressServices] and add imports: [AppModule] then I got this error:
NotSupportedError: This name has already been registered in the registry.
Can you help me to solve that problem?