Angular + Redux Jasmine testing "Cannot read property 'dispatch' of undefined" randomly thrown in runs

608 views Asked by At

I have an integration test that is dependant on 2 services which I am providing to the testbed with stubs.

When I am testing a function updateCategory() in the subscribe block of this category I have a function ngRedux.dispatch({type: something})

The error: TypeError: Cannot read property 'dispatch' of undefined gets randomly thrown out even though the service is stubbed and the function is provided. For some odd reason it thinks it's a property of the service.

This error gets thrown, without making any changes whatsoever to the test, just refreshing the karma page:

  • At a random test each time.
  • Sometimes all test pass with the error only in the console.
  • Sometimes it stops trying other tests after throwing the error.
  • Sometimes it throws the error with all tests passing.

It's so unpredictable it just makes no sense to me at all.

TestBed Configuration:

describe('AdminCategoriesComponent', () => {
  let component: AdminCategoriesComponent;
  let fixture: ComponentFixture<AdminCategoriesComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MatSnackBarModule,
        ReactiveFormsModule,
        FormsModule,
        MatInputModule,
        MatExpansionModule,
        BrowserAnimationsModule,
        NgReduxTestingModule
      ],
      declarations: [AdminCategoriesComponent],
      providers: [
        { provide: AdminService, useClass: AdminStub },
        { provide: NgRedux, useclass: MockNgRedux }
      ],
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents()
      .then(() => {
        MockNgRedux.reset();
        fixture = TestBed.createComponent(AdminCategoriesComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
  }));

Test configuration:

 it('should update category', () => {

    component.categoryID = 1;
    component.categoryTitle = 'Test Category Title';
    component.categoryDescription = 'Test Category Description';
    component.ngOnInit();

    fixture.detectChanges();

    component.categoryForm.value.categoryTitle = 'New Category Title';
    component.categoryForm.value.categoryDescription =
      'New Category Description';

    component.updateCategory();

    fixture.detectChanges();
    expect(component.localLoading).toBeFalsy();
  });

Without the test above -- the error does not get thrown. And without the dispatch function in that subscribe block, the error doesn't get thrown either.

1

There are 1 answers

0
SebastianG On BEST ANSWER

angular-redux module is outdated and just generally garbage, this becomes a lot more obvious when you try to run any tests with it. A year after switching to @ngrx/store and properly learning how to work with observables, the solution is to use @ngrx/store or fork angular-redux and fix the bugs yourself.