Angular-Karma Solution of NullInjectorError in UnitTest [ionic4]
Jasmine and Karma are used in Unit Testing Angular. Though it has no problems in a Service Class Testing, Component Testing occurs so many errors related to module injection.
In addition, the solution of the errors depends on the error, so it is not only one. It’s very complex.
Setting “providers"
Error as the following.
NullInjectorError: StaticInjectorError(DynamicTestModule)[AppVersion]:
In most cases, the solution are to set modules which are used in module.ts of testing target, to “providers" of TestingModule.
Solution
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TestPage ], providers: [AppVersion] }) .compileComponents(); }));
RouterTestingModule
Error as the following.
NullInjectorError: StaticInjectorError(DynamicTestModule)[Router -> Location]:
Solution
If it inject a NavController in PageComponent, the solution is as the following.
import {RouterTestingModule} from "@angular/router/testing"; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TestPage ], imports: [ RouterTestingModule ] }) .compileComponents(); }));
TranslateTestingModule
Error as the following.
NullInjectorError: StaticInjectorError(DynamicTestModule)[TranslateService]:
Solution
Create mock as the following.
translate-testing.module
import { Injectable, NgModule, Pipe, PipeTransform } from '@angular/core'; import { TranslateModule, TranslatePipe, TranslateService } from '@ngx-translate/core'; import { Observable, of } from 'rxjs'; const translations: any = {}; @Pipe({ name: 'translate' }) export class TranslatePipeMock implements PipeTransform { public name = 'translate'; public transform(query: string, ...args: any[]): any { return query; } } @Injectable() export class TranslateServiceStub { public get(key: T): Observable { return of(key); } public addLangs(langs: string[]) { } public setDefaultLang(lang: string) { } public getBrowserLang(): string { return 'en'; } public use(lang: string) { } } @NgModule({ declarations: [ TranslatePipeMock ], providers: [ { provide: TranslateService, useClass: TranslateServiceStub }, { provide: TranslatePipe, useClass: TranslatePipeMock }, ], imports: [ TranslateModule.forRoot({}) ], exports: [ TranslatePipeMock, TranslateModule ] }) export class TranslateTestingModule { }
Set the Mock to “imports" in TestingModule.
import {TranslateTestingModule} from "@/your-path/translate-testing.module"; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TestPage ], imports: [ TranslateTestingModule ], }) .compileComponents(); }));
Error @NgModule.entryComponents
In case that target component use other Components.
Error: No component factory found for YOURComponent. Did you add it to @NgModule.entryComponents?
Solution
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [YOURComponent], }).overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [YOURComponent] } }) .compileComponents(); }));
Error ModalController
If it inject ModalController in target Class.
NullInjectorError: StaticInjectorError(DynamicTestModule)[TestPage -> ModalController]:
Solution
let modalSpy = jasmine.createSpyObj('Modal', ['present']); let modalCtrlSpy = jasmine.createSpyObj('ModalController', ['create']); modalCtrlSpy.create.and.callFake(function () { return modalSpy; }); beforeEach(async(() => { TestBed.configureTestingModule({ providers: [ { provide: ModalController, useValue: modalCtrlSpy } ] }).compileComponents(); }));
Error of APP_BASE_HREF
Error as the following.
Error: No base href set. Please provide a value for the APP_BASE_HREF token or add a base element to the document.
Solution
The error can be resolved with the following.
beforeEach(async(() => { TestBed.configureTestingModule({ providers: [ {provide: APP_BASE_HREF, useValue: '/'} ] }).compileComponents(); }));
Discussion
New Comments
No comments yet. Be the first one!