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