1
votes

I am testing a component which displays some data from ngrx store, when button is clicked.

On button click, the route params change

  <button
    class="submit"
    [routerLink]="['/page']"
    [queryParams]="{
      period_start: '01.01.19',
      period_end: '01.01.19',
      submit_search: '->'
    }"
  >
  </button>

I subscribe to the change in route params on init and dispatch a store action, if one of the params is submit_search. No text is logged when running the tests.

  ngOnInit() {
    this.route.queryParams.subscribe(params => {
      console.log('Before params.submit_search');
      if (params.submit_search) {
        console.log('In params.submit_search');
        this.store.dispatch(...);
      }
    });
  }

This test knows that route after click has changed (this test passes):

    it('should set route params to filter params', fakeAsync(() => {
      const filterButtonElement = fixture.nativeElement.querySelector('.submit');
      filterButtonElement.click();
      tick();
      expect(location.path()).toEqual(
        `'/page?period_start=01.01.19&period_end=01.01.19&submit_search=-%3E'`
      );
    }));

But this test says that 'dispatch' has been called 0 times, so the subscription has not registered the change in route:

describe('SomeComponent', () => {
  let dispatchSpy;
  let location: Location;
  let router: Router;
  let route: ActivatedRoute;
  let component: SomeComponent;
  let fixture: ComponentFixture<SomeComponent>;
  let mockStore: MockStore<State>;
  let mockGetData: MemoizedSelector<State, SomeData[]>;
  const initialState = {};
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        RouterTestingModule.withRoutes([
          {
            path: 'page',
            component: SomeComponent
          }
        ]),
      ],
      declarations: [SomeComponent],
      providers: [
        provideMockStore({ initialState }),
        { provide: ActivatedRoute, useValue: { queryParams: from([]) } }
      ]
    }).compileComponents();
    router = TestBed.get(Router);
    route = TestBed.get(ActivatedRoute);
    location = TestBed.get(Location);
  }));
  beforeEach(() => {
    fixture = TestBed.createComponent(SomeComponent);
    component = fixture.componentInstance;
    mockStore = TestBed.get(Store);
    mockGetData = mockStore.overrideSelector(SomeSelectors.selectData, []);
    router.initialNavigation();
    fixture.detectChanges();
  });
    it('should dispatch store action', fakeAsync(() => {
      dispatchSpy = spyOn(mockStore, 'dispatch');
      const filterButtonElement = fixture.nativeElement.querySelector('.submit');
      filterButtonElement.click();
      tick();
      expect(dispatchSpy).toHaveBeenCalledTimes(1);
    }));
});

Why is the subscription not triggered? Should I provide the ActivatedRoute params differently?

1
Put a console.log('In params.submit_search') in the if(params.submit_search) and put a console.log('Before spying'); before spyOn(mockStore, 'dispatch'); and make sure In params.submit_search gets logged after Before spying and not before. If Chrome or a browser appears when you run the test, you can put a debugger; at the same location (after the if statement) and see if it becomes tripped as well. It it tough because I can't see everything you have.AliF50
Nothing in the route params subscription is logged, so the subscription is the problemKetija Krista

1 Answers

1
votes

It seems like you have to mock the ActivatedRoute to what you would like.

Change the provide of ActivatedRoute to as such, this should hopefully get you unblocked.

  import { of } from 'rxjs';
  //.....
  providers: [.... 
              {
                 provide: ActivatedRoute, 
                 useValue: { queryParams: of({ submit_search: 'hello', })
               }],

Now to get a way to change the value of the queryParams, you can do:

let dispatchSpy;
let queryParamsValue = new BehaviorSubject({ submit_search: 'hello', });
....
// bind this behavior subject to queryParams in the provider
  useValue: { queryParams: queryParamsValue }

Then in your tests you can do, queryParamsValue.next({ ... }); to change the value of what the queryParams are and start your subscription.