I'm brand new to Angular2 and trying to write a test in the app.component.spec.ts file. My application is relatively simple, besides the fact that it imports LoginComponent and LogoutComponent from a 3rd party library (written by coworkers). The components are used in a route login or logout respectively right now, pretty simple stuff. Running ng serve compiles ok and the application runs "smoothly". Running ng test, however, gives me this error:
NullInjectorError: StaticInjectorError(DynamicTestModule)[LogoutComponent -> SessionService]:
StaticInjectorError(Platform: core)[LogoutComponent -> SessionService]:
NullInjectorError: No provider for SessionService!
LogoutComponent is imported from a different project. Does this error mean I need to go into that project and make some changes, or am I supposed to be mocking SessionService somehow in my project?
Spec code:
import {} from 'jasmine';
import {async, TestBed} from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import {AuthErrorStateService, LogoutComponent} from '@custom-library';
import {AppComponent} from './app.component';
import {AppErrorStateService} from './core/error-states/app-error-state.service';
import {TopNavComponent} from './core/top-nav/top-nav.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed
.configureTestingModule({
imports: [RouterTestingModule],
providers: [
AppErrorStateService, AuthErrorStateService
],
declarations: [AppComponent, TopNavComponent, LogoutComponent],
})
.compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'My App'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('My App');
});
it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toEqual('Welcome to My App!');
});
});
The problem is declaring multiple components in TestBed like so
declarations: [AppComponent, TopNavComponent, LogoutComponent]
results in multiple components being instantiated when the test calls compileComponents(). When that happens, each component in the declarations array needs its dependencies declared in the providers array to complete instantiation. One of the declared components depends on SessionService, but that service is not present in providers, so you get the NullInjectorError.
There are two solutions to this:
declarations array and add
schemas: [ CUSTOM_ELEMENTS_SCHEMA ] to the TestBed configuration
object providers arrayIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With