J-man
J-man

Reputation: 1833

Why am I getting "No provider for ReducerManager!" error on unit tests for lazy loaded Angular 6 app with ngrx?

I have a lazy loading Angular 6 app that uses ngrx. I have an:

app.module.ts
shared.module.ts
core.module.ts

The core module has things like the footer and header. There are no store/ngrx related stuff here, but the unit tests for the header (that were working before implementing ngrx) keep failing with the following error:

StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]: NullInjectorError: No provider for ReducerManager!

The only thing I can think of is that the StoreModule is not imported into the CoreModule. But should it? Why are the tests failing when the header has nothing to do with state?

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();
});

Upvotes: 2

Views: 5433

Answers (2)

Leo Lanese
Leo Lanese

Reputation: 496

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();
});

Upvotes: 1

timdeschryver
timdeschryver

Reputation: 15505

Because your component uses the NgRx store, you also have to import the store inside the TestBed.

Upvotes: 1

Related Questions