You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试时无法触发forkJoin的subscribe代码块的解决方法

问题分析与解决

核心原因

测试中forkJoin的subscribe回调未执行,是因为RxJS的异步操作需要测试环境主动触发异步队列刷新——Jest默认不会自动等待RxJS的异步流完成,即便用了async(),也需要明确等待异步操作结束。

另外注意组件代码里的笔误:this.value = res.summary;应该是res.summary2,否则会取到不存在的属性,导致逻辑出错。

解决方案

方法1:使用fakeAsync + tick()(推荐)

Angular测试工具提供的fakeAsync可以模拟时间环境,tick()会立即刷新所有待处理的异步任务(包括RxJS的Observable流),确保subscribe回调执行:

it('setup()', fakeAsync(() => {
  const expectedData = mockData;
  // 模拟service返回完成的Observable
  const summary1Spy = jest.spyOn(service1, 'getSummary').mockReturnValue(of(expectedData));
  const summary2Spy = jest.spyOn(service2, 'getSummary').mockReturnValue(of({/* 模拟返回值 */}));

  component.setup();
  tick(); // 触发所有RxJS异步操作,执行subscribe回调
  fixture.detectChanges(); // 若需要更新组件视图,可添加此句

  // 断言逻辑
  expect(summary1Spy).toHaveBeenCalled();
  expect(summary2Spy).toHaveBeenCalled();
  expect(component.value).toEqual(/* 预期的summary2返回值 */);
}));

方法2:手动等待Observable完成

如果不想用fakeAsync,可以修改组件的setup方法返回forkJoin的Observable,再在测试中等待其完成:

首先修改组件代码:

setup(): Observable<any> { 
  const observables$ = {
    summary1: this.service1.getSummary(data),
    summary2: this.service2.getSummary()
  };
  const forkJoin$ = forkJoin(observables$);
  forkJoin$.subscribe((res) => {
    if(res.summary1) {
      // 操作逻辑
    }
    if(res.summary2) {
      this.value = res.summary2; // 修正笔误
    }
  });
  return forkJoin$;
}

然后修改测试代码:

it('setup()', async() => {
  const expectedData = mockData;
  const summary1Spy = jest.spyOn(service1, 'getSummary').mockReturnValue(of(expectedData));
  const summary2Spy = jest.spyOn(service2, 'getSummary').mockReturnValue(of({/* 模拟值 */}));

  await lastValueFrom(component.setup());
  fixture.detectChanges();

  expect(summary1Spy).toHaveBeenCalled();
  expect(summary2Spy).toHaveBeenCalled();
  expect(component.value).toEqual(/* 预期值 */);
});

额外注意点

  • forkJoin要求所有内部Observable都完成才会发射值,你的mock返回of()是没问题的(因为of()会立即完成);如果mock的是不会完成的Observable(比如BehaviorSubject),需要手动调用complete()。
  • 组件代码中的res.summary是明显笔误,必须修正为res.summary2,否则即便进入回调,this.value也会被赋值为undefined。

内容的提问来源于stack exchange,提问作者Aastha B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:35:06