I'm starting with Jest and Unit test. I need to create unit tests for an already existing big application on angular 11, and I start by testing services.
Here is my BaseService
. Most of my other services expends from this one.
@Injectable({
providedIn: 'root'
})
export class BaseService {
protected apiHost: string;
protected httpClient: HttpClient;
protected httpClientWithInterceptor: HttpClient;
protected configurationService: ConfigurationService;
protected translate: TranslateService;
constructor(
injector: Injector,
) {
this.configurationService = injector.get(ConfigurationService);
this.translate = injector.get(TranslateService);
this.apiHost = this.configurationService.configuration.apiHost;
this.httpClient = new HttpClient(injector.get(HttpBackend));
this.httpClientWithInterceptor = injector.get(HttpClient);
}
// ...
}
As you see, it inject some other services like HttpClient
, TranslateService
and ConfigurationService
.
I solved (I hope) the dependency for HttpClient
and TranslateService
but ConfigurationService
is still a problem. This is another internal service to fetch an appSettings.json file and it has its own dependencies.
export class ConfigurationService {
public configuration: Configuration;
constructor(private httpClient: HttpClient, httpBackend: HttpBackend) {
this.httpClient = new HttpClient(httpBackend);
this.getConfigurationFromUrl();
}
// ...
}
And now my test file for BaseService
describe('BaseService', () => {
let service: BaseService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
TranslateModule.forRoot(),
],
providers: [BaseService, ConfigurationService]
});
service = TestBed.inject(BaseService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
Form now it does nothing and npm test
return error
describe('BaseService', () => {
let service: BaseService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
TranslateModule.forRoot(),
],
providers: [BaseService, ConfigurationService]
});
service = TestBed.inject(BaseService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
the returned error
FAIL projects/web-components/src/app/shared/services/base.service.spec.ts
BaseService › should be created
TypeError: Cannot read property 'apiHost' of null
25 | // this.configurationService = injector.get(ConfigurationService);
26 | // this.translate = injector.get(TranslateService);
> 27 | this.apiHost = this.configurationService.configuration.apiHost;
at new BaseService (projects/web-components/src/app/shared/services/base.service.ts:27:60)
at Object.BaseService_Factory [as factory] (ng:\BaseService\ɵfac.js:5:10)
at R3Injector.Object.<anonymous>.R3Injector.hydrate (../packages/core/src/di/r3_injector.ts:412:29)
at R3Injector.Object.<anonymous>.R3Injector.get (../packages/core/src/di/r3_injector.ts:209:23)
at NgModuleRef$1.Object.<anonymous>.NgModuleRef$1.get (../packages/core/src/render3/ng_module_ref.ts:76:29)
at TestBedRender3.Object.<anonymous>.TestBedRender3.inject (../packages/core/testing/src/r3_test_bed.ts:278:48)
at Function.Object.<anonymous>.TestBedRender3.inject (../packages/core/testing/src/r3_test_bed.ts:167:33)
at projects/web-components/src/app/shared/services/base.service.spec.ts:19:23
at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:386:30)
at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:117:43)
at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:385:36)
at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/dist/zone.js:143:47)
Of course, a lot of other services extends from BaseService
and they all have there own dependencies.
So here are my questions :
- Did I chose the right way to implement unit tests ?
- Can you help me with this dependencies injections error please ?