Search code examples
angulartypescriptangular-routingangular-routerangular2-testing

How would I mock route queryParams in ngOnInit() in a spec test


Failed: Cannot read property 'queryParams' of null at

I'm assuming it's because I have the following in ngOnInit():

  ngOnInit() {
    this.route.queryParams.subscribe(async params => {
      this.userInfo = await JSON.parse(params['user_info']);
    });

So far I've tried constructing my unit test with the following:

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

  beforeEach(async(() => {
    routeStub = null;

    TestBed.configureTestingModule({
      declarations: [ AddItineraryPage ],
      imports: [IonicModule.forRoot(), FormsModule, ReactiveFormsModule, RouterTestingModule],
      providers: [
        {provide: ActivatedRoute, useValue: routeStub}
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(AddItineraryPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should create', () => {
    routeStub.queryParams = {
    displayName: '',
    dateOfBirth: '',
    email: '',
    photos: [],
    location: '',
    bio: '',
    intDestination: [],
    userId: ''};

    fixture.detectChanges();
    fixture.whenStable().then(() => {
      expect(component).toBeTruthy();

    });
  });
});

Solution

  • Cannot read property 'queryParams' of null

    So when the property queryParams is being called on the routeStub object, it is null. You initialized the routeStub to null, so it makes sense. ngOnInit() gets called the first time you call fixture.detectChanges(), so you need to assign something to the routeStub before you make that call.

    Also in your code, you call subscribe() on the queryParams, so you will need to assign an Observable-like object to the property. You can just use an actual Observable by using Observable.of().

    So your test code should look more like

    beforeEach(async(() => {
      routeStub = null;
      ...
      fixture = TestBed.createComponent(AddItineraryPage);
      component = fixture.componentInstance;
      // remove fixture.detectChanges() as it calls ngOnInit()
    }));
    
    it('should create', () => {
      routeStub = {
        queryParams: of({
          user_info: '{
            "displayName": "UserName"
          }'
          // not sure why you are calling `JSON.parse()`
          // but if you are doing that, then user_info should
          // be a JSON string
        })
      };
    
      fixture.detectChanges();
      fixture.whenStable().then(() => {
        expect(component.userInfo.displayName).toBe('UserName');
      });
    });