Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

151
Views
Jest Async tests are confusing me

Here is the scenario:

Using Jest/Spectator to test RXJS observable but can't seem to get to the line of code I want to test via my current setup

Component code -

  ngOnInit(): void {  
    this.authDetail$ = this.validateToken(this.token).pipe(
      takeUntil(this.unsubscribe$),
      catchError((error) => { 
        if (error) {
          // I want to test this next line...
          // But I never see it run...
          this.router.navigate(['unauthorized'], { replaceUrl: true });
        }
        // This only exists to satisfy the observable chain.
        return of({} as SomeModel);
      }),
    );
  }

  validateToken(token: string): Observable<SomeModel> {
    return this.authService.lookupByToken(token);
  }

Test-

  it('should redirect to "unauthorized" when error is thrown', (done) => {

      jest.spyOn(spectator.component, 'validateToken')
        .mockReturnValue(throwError({ status: 403 }) as any);

      spectator.component.validateToken('invalid_token').subscribe({
        next: (data) => {
          console.log('NEXT BLOCK: Should Have Thrown Error');
          done();
        },
        error: (error) => {
          expect(spectator.router.navigate).toHaveBeenCalledWith(
            ['unauthorized'],
            { replaceUrl: true },
          );
          expect(error).toBeTruthy(); 
          done();
        },
      });

      // This fires off the ngOnInit :)
      spectator.setRouteParam('token', 'INVALID_TOKEN');
    });

The issue I am having is that when the test runs I can see that I am receiving a 403 but the router.navigate is not being called. If I console.log that part of the subscribe block, in the component, I see that it's never reached.

How do I test that line of code?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I think I see your problem.

If you have:

catchError((error) => { 
        if (error) {
          // I want to test this next line...
          // But I never see it run...
          this.router.navigate(['unauthorized'], { replaceUrl: true });
        }
        // This only exists to satisfy the observable chain.
        return of({} as SomeModel);
      }),

The return of(.. will make it go to the success block and not the error block when you subscribe to that RxJS stream because the catchError is saying if there is an error, handle it this way and return this (of(..) for the stream.

I see you're expecting the navigate call in the error part of the stream.

I would try changing the test to this:

it('should redirect to "unauthorized" when error is thrown', (done) => {

      jest.spyOn(spectator.component, 'validateToken')
        .mockReturnValue(throwError({ status: 403 }) as any);

      // This fires off the ngOnInit :)
      spectator.setRouteParam('token', 'INVALID_TOKEN');
      // subscribe to authDetail$ after it has been defined in ngOnInit
      spectator.component.authDetail$.pipe(take(1)).subscribe({
         next: (result) => {
           expect(spectator.router.navigate).toHaveBeenCalledWith(
            ['unauthorized'],
            { replaceUrl: true },
          );
          expect(result).toBeTruthy();
          done();
         }
      });
    });
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!