title: Unit test queryParams subscription (Angular5)
body: <p>i'm having problems testing the logic inside ActivatedRoute queryParams subscription.</p>
  
  <pre><code>constructor(private router: Router, private route: ActivatedRoute, private auth: AuthService) {}
  
  ngOnInit(): void {
    this.route.queryParams.subscribe((params:any) =&gt; {
      if(params['data']) {
        this.handle(params['data']);
      } else {
        if (this.auth.isAuthenticated()) {
          this.router.navigate(['/home']);
        }
      }
    });
  }
  </code></pre>
  
  <p>I would like to test:</p>
  
  <ul>
  <li>If <code>this.handle()</code> is triggered when mocked <code>params['data']</code> is supplied</li>
  <li>If there is no params and <code>this.auth.isAuthenticated()</code> returns <code>true</code> that <code>this.router.navigate</code> is called</li>
  </ul>
  
  <p>I have tried multiple things and i'm running out of ideas.</p>
  
  <p>My test file:</p>
  
  <pre><code>describe('TestComponent', () =&gt; {
    let component: TestComponent;
    let fixture: ComponentFixture&lt;TestComponent&gt;;
  
    const mockService = {
      navigate: jasmine.createSpy('navigate'),
      isAuthenticated: jasmine.createSpy('isAuthenticated'),
      queryParams: jasmine.createSpy('queryParams')
    };
  
    beforeEach(async(() =&gt; {
      TestBed.configureTestingModule({
        declarations: [TestComponent],
        providers: [
          { provide: Router, useValue: mockService },
          { provide: ActivatedRoute, useValue: mockService },
          { provide: AuthService, useValue: mockService }
        ]
      }).compileComponents();
  
      fixture = TestBed.createComponent(TestComponent);
      component = fixture.componentInstance;
  
      mockService.navigate.calls.reset();
    }));
  
    it('should create the test component', () =&gt; {
      expect(component).toBeTruthy();
    });
  
    it('should navigate away when authenticated', () =&gt; {
      mockService.isAuthenticated.and.returnValue(true);
      mockService.queryParams.and.callFake((data, params) =&gt; new Observable(o =&gt; o.next({ params: {} })));
      component.ngOnInit();
      expect(mockService.navigate).toHaveBeenCalledWith(['/home']);
    });
  });
  </code></pre>
  
  <p>But with that i get <code>TypeError: this.route.queryParams.subscribe is not a function</code>. I know that <code>mockService.isAuthenticated.and.returnValue(true);</code> is working correctly because before using subscription to params i had only this if statement inside <code>ngOnInit()</code>.</p>
  
  <p>I have tried to change the mockService to:</p>
  
  <pre><code>const mockService = {
    navigate: jasmine.createSpy('navigate'),
    isAuthenticated: jasmine.createSpy('isAuthenticated'),
    queryParams: {
      subscribe: jasmine.create('subscribe')
    }
  };
  </code></pre>
  
  <p>I also tried with:</p>
  
  <pre><code>const mockService = {
    navigate: jasmine.createSpy('navigate'),
    isAuthenticated: jasmine.createSpy('isAuthenticated'),
    queryParams: {
      subscribe: Observable.of({ params: {} })
    }
  };
  </code></pre>
  
  <p>But no success, for those last two i get <code>Expected spy navigate to have been called with [ [ '/home' ] ] but it was never called.</code></p>
  
  <p>So does someone know how to correctly test logic inside querParams subscription?</p>