为什么我在使用 ngrx 延迟加载 Angular 6 应用程序的单元测试中收到 "No provider for ReducerManager!" 错误?
Why am I getting "No provider for ReducerManager!" error on unit tests for lazy loaded Angular 6 app with ngrx?
我有一个 延迟加载 Angular 6 应用程序使用 ngrx。我有一个:
app.module.ts
shared.module.ts
core.module.ts
核心模块有页脚和 header 之类的东西。这里没有 store/ngrx 相关的东西,但是 header 的单元测试(在实施 ngrx 之前工作)一直失败并出现以下错误:
StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]:
NullInjectorError: No provider for ReducerManager!
我唯一能想到的就是StoreModule
没有导入到CoreModule
。但应该吗?为什么 header 与状态无关时测试失败?
app.module.ts
@NgModule({
declarations: [
AppComponent,
LoginComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
CoreModule,
SharedModule.forRoot(),
StoreModule.forRoot({}),
EffectsModule.forRoot([]),
!environment.production ? StoreDevtoolsModule.instrument({
maxAge: 5 // retains last 5 states
}) : []
],
providers: [],
bootstrap: [ AppComponent ]
})
core.module.ts
@NgModule({
imports: [
CommonModule,
],
exports: [
CommonModule,
HeaderComponent,
FooterComponent
],
declarations: [
HeaderComponent,
FooterComponent,
]
})
shared.module.ts
@NgModule({
imports: [
CommonModule,
HttpClientModule
],
exports: [
CommonModule,
MyComponent
],
declarations: [ MyComponent]
})
export class SharedModule {
** header.component.spec.ts**
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
let debugEl: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
ProductsModule,
CustomersModule
],
declarations: [ HeaderComponent ],
providers: [
{ provide: myService, useValue: new MyService() },
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
debugEl = fixture.debugElement;
fixture.detectChanges();
});
因为您的组件使用 NgRx 存储,您还必须在 TestBed
.
中导入存储
import { Store, StoreModule } from '@ngrx/store';
describe('test:', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HeldMessagesTabsPageModule,
StoreModule.forRoot(
{
messagesRoot: combineReducers(reducers.reducers)
},
{
initialState: { messagesRoot: { messagesRoot: { template: templateInitialState } } }
}
)
],
const store: Store<reducers.State>;
}
beforeEach(() => {
store = TestBed.get(Store);
spyOn(store, 'dispatch').and.callThrough();
});
我有一个 延迟加载 Angular 6 应用程序使用 ngrx。我有一个:
app.module.ts
shared.module.ts
core.module.ts
核心模块有页脚和 header 之类的东西。这里没有 store/ngrx 相关的东西,但是 header 的单元测试(在实施 ngrx 之前工作)一直失败并出现以下错误:
StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]:
NullInjectorError: No provider for ReducerManager!
我唯一能想到的就是StoreModule
没有导入到CoreModule
。但应该吗?为什么 header 与状态无关时测试失败?
app.module.ts
@NgModule({
declarations: [
AppComponent,
LoginComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
CoreModule,
SharedModule.forRoot(),
StoreModule.forRoot({}),
EffectsModule.forRoot([]),
!environment.production ? StoreDevtoolsModule.instrument({
maxAge: 5 // retains last 5 states
}) : []
],
providers: [],
bootstrap: [ AppComponent ]
})
core.module.ts
@NgModule({
imports: [
CommonModule,
],
exports: [
CommonModule,
HeaderComponent,
FooterComponent
],
declarations: [
HeaderComponent,
FooterComponent,
]
})
shared.module.ts
@NgModule({
imports: [
CommonModule,
HttpClientModule
],
exports: [
CommonModule,
MyComponent
],
declarations: [ MyComponent]
})
export class SharedModule {
** header.component.spec.ts**
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
let debugEl: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
ProductsModule,
CustomersModule
],
declarations: [ HeaderComponent ],
providers: [
{ provide: myService, useValue: new MyService() },
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
debugEl = fixture.debugElement;
fixture.detectChanges();
});
因为您的组件使用 NgRx 存储,您还必须在 TestBed
.
import { Store, StoreModule } from '@ngrx/store';
describe('test:', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HeldMessagesTabsPageModule,
StoreModule.forRoot(
{
messagesRoot: combineReducers(reducers.reducers)
},
{
initialState: { messagesRoot: { messagesRoot: { template: templateInitialState } } }
}
)
],
const store: Store<reducers.State>;
}
beforeEach(() => {
store = TestBed.get(Store);
spyOn(store, 'dispatch').and.callThrough();
});