简体   繁体   中英

NullInjectorError: StaticInjectorError(DynamicTestModule) When Testing in Angular 2

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:

  • only declare one component in the declarations array and add schemas: [ CUSTOM_ELEMENTS_SCHEMA ] to the TestBed configuration object
  • continue to declare multiple components and add all the dependencies (or a mock thereof) for each component to the providers array

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM