Получение NullInjectorError: нет поставщика для ошибки хранилища при попытке запустить тесты Angular - PullRequest
0 голосов
/ 13 июля 2020

app.component.ts

...
constructor(private store: Store<fromAppState.AppState>) {}
  ngOnInit() {
    this.store.dispatch(new fromAppActions.Load());
...

app.state.ts

export interface AppState {
  structure: Structure;
  buttons: number[];
  bars: Bar[];
  limit: number;
  isLoading: boolean;
  error: string;
}
export const initialState: AppState = {
  buttons: [],
  structure: null,
  bars: [],
  limit: 0,
  isLoading: false,
  error: '',
};
const getState = createFeatureSelector<AppState>('myApp');
...

app.component.spe c .ts

 describe('AppComponent', () => {
  @Component({
    selector: 'app-loader',
    template: '<div></div>',
  })
  class FakeLoaderComponent {
    @Input() loading: boolean;
  }
  let component: AppComponent;
  let mockStore: MockStore;
  let mockBarsSelector: MemoizedSelector<fromAppState.AppState, Bar[]>;
  // const storeMock = jasmine.createSpyObj('Store', ['select']);
  let buttons$: Observable<number[]> = of([45, 23, -8, -12]);
  let buttons: number[] = [45, 23, -8, -12];
  let loading$: Observable<boolean> = of(true);
  let structure: Structure = {
    buttons: [45, 23, -8, -12],
    bars: [15, 34, 7, 87],
    limit: 150,
  };
  let barsObject: Bar[] = [
    { value: 15, newValue: Math.round(15 * 100) / 150 },
    { value: 34, newValue: Math.round(34 * 100) / 150 },
    { value: 7, newValue: Math.round(7 * 100) / 150 },
    { value: 87, newValue: Math.round(87 * 100) / 150 },
  ];
  
  let fixture: ComponentFixture<AppComponent>;
  beforeEach(async(() => {
    fixture = TestBed.createComponent(AppComponent);
   
    component = fixture.componentInstance;

    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        MaterialModule,
        StoreModule.forRoot({}, {}),
      ],
      declarations: [AppComponent, FakeLoaderComponent],
      providers: [provideMockStore()],
    }).compileComponents();
    component.bars = barsObject;
    component.limit = structure.limit;
    component.selectedProgressBar = -1;
    component.componentActive = true;
    component.buttons$ = buttons$;
    component.loading$ = loading$;

    mockStore = TestBed.inject(MockStore);
    mockStore.overrideSelector(fromAppState.getIsLoading, false);
    mockStore.overrideSelector(fromAppState.getBars, barsObject);
    mockStore.overrideSelector(fromAppState.getButtons, buttons);
    mockStore.overrideSelector(fromAppState.getStructure, structure);
    mockStore.overrideSelector(fromAppState.getError, '');
    mockBarsSelector = mockStore.overrideSelector(
      fromAppState.getBars,
      barsObject
    );
    fixture.detectChanges();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});

app.module.ts

@NgModule({
  declarations: [AppComponent, LoaderComponent],

  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MaterialModule,
    HttpClientModule,
    StoreModule.forRoot({}, {}),
    EffectsModule.forRoot([AppEffects]),
    StoreModule.forFeature('myApp', AppReducer),
    StoreDevtoolsModule.instrument({
      name: 'My DevTools',
      maxAge: 50,
      logOnly: environment.production,
    }),
  ],
  providers: [AppService],
  bootstrap: [AppComponent],
})
export class AppModule {}

Когда я запускаю ng test, я получаю эту ошибку: Ошибка: R3InjectorError (DynamicTestModule) [Store -> Store]: NullInjectorError: Нет поставщика для Store! свойства ошибки: Object ({ngTempTokenPath: null, ngTokenPath: ['Store', 'Store']}) в Jasmine

Нужно ли мне также импортировать редуктор в файл spe c?

1 Ответ

0 голосов
/ 13 июля 2020

Попробуйте создать компонент после настройки TestBed.

    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        MaterialModule,
        StoreModule.forRoot({}, {}),
      ],
      declarations: [AppComponent, FakeLoaderComponent],
      providers: [provideMockStore()],
    }).compileComponents();


// do this AFTER configuration

fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
    

И, как Андрей упомянул в комментариях, вы можете использовать только реальный Store или provideMockStore - невозможно использовать оба на В то же время, AFAIK, это может привести к странному поведению.

...