【问题标题】:Jest Async tests are confusing me开玩笑的异步测试让我很困惑
【发布时间】:2022-01-22 00:41:54
【问题描述】:

这是场景:

使用 Jest/Spectator 测试可观察的 RXJS,但似乎无法通过我当前的设置进入我想要测试的代码行

组件代码-

  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);
  }

测试-

  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');
    });

我遇到的问题是,当测试运行时,我可以看到我收到了 403,但没有调用 router.navigate。如果我在组件中 console.log 订阅块的那部分,我发现它从未到达过。

如何测试那行代码?

【问题讨论】:

  • catchError里面,如果你console.log(error),你会得到什么?
  • @AliF50 我得到一个{status: 403} 我看到了我模拟的错误,但我不知道我是否应该在我的组件中看到路由器调用,或者它是否只是为了测试我是否抓住了来自模拟的错误。在这一点上感到困惑。

标签: javascript angular unit-testing jestjs angular-spectator


【解决方案1】:

我想我看到了你的问题。

如果你有:

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);
      }),

当您订阅 RxJS 流时,return of(.. 将使其进入成功块而不是错误块,因为catchError 表示如果有错误,以这种方式处理并返回它 (@987654324 @) 用于流。

我看到您在流的错误部分期待导航调用。

我会尝试将测试更改为:

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();
         }
      });
    });

【讨论】:

  • 干得好!!!!这完全解决了我的问题!感谢您的帮助:D
猜你喜欢
  • 2018-02-22
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 2022-01-01
  • 2017-12-18
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多