如何使用Jest Angular单元测试switchMap和其他操作

xqnpmsa8  于 2023-11-15  发布在  Jest
关注(0)|答案(2)|浏览(180)

Angular 15,想要测试switchMap,filter,tap和take。
我试着测试我的可观察性:

private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null)
private refreshTokenSubject$ = this.refreshTokenSubject.asObservable()

handleRefresh(){
 return this.refreshTokenSubject$.pipe(
   tap(() => console.log('refresh token')),
   filter((token) => token)),
   take(1),
   switchMap((token) => {
      return next.handle(this.addToken(req,token);
   })
 ) 
}

字符串
我在做这个:

beforeEach(()=>{
  interceptor = TestBed.inject(RefreshTokenInterceptor)
  requestMock = new HttpRequest("GET", "/fakeRequest")
})

it("should", () => {
  interceptor["addToken"] = jest.fn().mockReturnValue(requestMock)
  
  const next = {
    handle: jest.fn().mockImplementation(()=>{
      return of()
    }
  } as HttpHandler

  const result = interceptor["refreshTokenSubject$"]
  interceptor["handleRefresh"](requestMock, next)
  result.subscribe(() => {
    expect(next.handle).toBeCalled()
  })
})


测试通过,但覆盖率表明未测试tap、filter、take和switchMap行

0md85ypi

0md85ypi1#

覆盖率并不一定是测试质量的一个好指标(有时候事情不能被覆盖)。也就是说,你仍然可以通过100%的覆盖率(如静态分析和覆盖率报告所报告的),然后真实的100%的覆盖率(每一个可能的路径都被覆盖)。

  • tap => mock console.log并根据调用量Assert
  • filter =>至少测试一次真令牌和一次假令牌
  • take => mock switchMap,根据调用回调的次数进行Assert
  • switchMap =>总是很难测试的。在测试对象的发射中添加一个受控的延迟/去抖动,这样你就可以在它过期之前发射,并且保证switchMap会发生。然后根据调用的数量Assert。如果你可以模拟你的handle来检查它是否已经正确地和语义地“取消”/“切换”了
6ju8rftf

6ju8rftf2#

你的代码中有几个问题:

缺少;

在某些情况下,缺少;实际上会导致意外的副作用。请尝试始终设置它们。

您不进行异步测试

测试用例在subscribe块之前结束,因此expect被调用。有几种方法可以测试异步代码。此时最简单的方法是添加done处理程序。

it("should", done => {
  interceptor["addToken"] = jest.fn().mockReturnValue(requestMock);
  
  const next = {
    handle: jest.fn().mockImplementation(()=>{
      return of()
    }
  } as HttpHandler;

  const result = interceptor["refreshTokenSubject$"];
  interceptor["handleRefresh"](requestMock, next);
  result.subscribe(() => {
    expect(next.handle).toBeCalled();
    done();
  })
})

字符串
即使我建议使用笑话弹珠超过这一点。

刷新令牌为null

你期望流如何传递filter函数?你的刷新令牌总是以null开始,因此不会到达订阅处理程序。

相关问题