javascript NullInjectorError: StaticInjectorError(DynamicTestModule) 在 Angular 2 中测试时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54952009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:28:58  来源:igfitidea点击:

NullInjectorError: StaticInjectorError(DynamicTestModule) When Testing in Angular 2

javascriptangularunit-testingfrontendangular2-services

提问by Ryan Sperzel

I'm brand new to Angular2 and trying to write a test in the app.component.spec.tsfile. 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 servecompiles ok and the application runs "smoothly". Running ng test, however, gives me this error:

我是 Angular2 的新手,并试图在app.component.spec.ts文件中编写一个测试。我的应用程序相对简单,除了它从 3rd 方库(由同事编写)导入 LoginComponent 和 LogoutComponent 之外。这些组件现在分别用于路由登录或注销,非常简单。运行ng serve编译正常,应用程序“平稳”运行。ng test但是,Running给了我这个错误:

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?

LogoutComponent 是从不同的项目导入的。此错误是否意味着我需要进入该项目并进行一些更改,还是应该在我的项目中以某种方式模拟 SessionService?

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!');
  });
});

回答by The Head Rush

The problem is declaring multiple components in TestBedlike so

问题是TestBed像这样声明多个组件

 declarations: [AppComponent, TopNavComponent, LogoutComponent]

results in multiple components being instantiated when the test calls compileComponents(). When that happens, each component in the declarationsarray needs its dependencies declared in the providersarray to complete instantiation. One of the declared components depends on SessionService, but that service is not present in providers, so you get the NullInjectorError.

导致在测试调用时实例化多个组件compileComponents()。发生这种情况时,declarations数组中的每个组件都需要在providers数组中声明其依赖项才能完成实例化。声明的组件之一依赖于SessionService,但提供程序中不存在该服务,因此您将获得NullInjectorError.

There are two solutions to this:

对此有两种解决方案:

  • only declare one component in the declarationsarray and add schemas: [ CUSTOM_ELEMENTS_SCHEMA ]to the TestBedconfiguration object
  • continue to declare multiple components and add all the dependencies (or a mock thereof) for each component to the providersarray
  • 只在declarations数组中声明一个组件并添加 schemas: [ CUSTOM_ELEMENTS_SCHEMA ]TestBed配置对象中
  • 继续声明多个组件并将每个组件的所有依赖项(或其模拟)添加到 providers数组中