Jest异步测试让我很困惑



以下是场景:

使用Jest/Stator测试RXJS observable,但似乎无法通过当前设置测试我想要的代码行

组件代码-

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.navigation。如果我在组件中console.log订阅块的那一部分,我会发现它从未被访问过。

我该如何测试那行代码?

我想我明白你的问题了。

如果您有:

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表示如果存在错误,则以这种方式处理它,并为流返回this(of(..(。

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

我会尝试将测试更改为:

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

相关内容

  • 没有找到相关文章

最新更新