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

如何在Jasmine中测试错误响应?Angular组件测试问题排查

Angular组件ngOnChanges错误处理测试问题分析与修复

问题场景

组件核心代码:

ngOnChanges() {
  this.searchCriteria$ = this.bookingService.getSearchCriteria(this.booking.id).pipe(
    catchError((err) => {
      this.error$ = of(err);
      return EMPTY;
    })
  );
}

测试时遇到两个问题:

  1. 初始测试报错:TypeError: Cannot read properties of undefined (reading 'subscribe')
    测试代码:
    fit('should set error loading search criteria failed', () => {
      const errorMessage = 'Error getting search criteria';
      bookingService.getSearchCriteria.and.returnValue(throwError(() => new Error(errorMessage)));
    
      component.ngOnChanges();
    
      component.error$.subscribe((error) => {
        expect(error).toBe(errorMessage);
      });
    });
    
  2. 添加component.searchCriteria$.subscribe(() => {})后,报错变为:Expected Error: Error getting search criteria to be 'Error getting search criteria'.

正常响应的测试用例可成功执行,仅错误分支测试失败。

问题原因

  1. 第一个错误根源:error$未提前初始化。组件中error$仅在catchError逻辑内赋值,而catchError需要searchCriteria$被订阅才会触发。初始测试未订阅searchCriteria$,导致error$始终为undefined,订阅时触发类型错误。
  2. 第二个错误根源:error$接收的是Error对象,测试中直接用字符串errorMessage做全等断言,类型不匹配导致断言失败。

修复方案

步骤1:提前初始化组件内的error$

在组件类中声明error$时直接初始化,避免出现undefined:

error$: Observable<Error | null> = of(null);

步骤2:修正错误分支测试代码

必须订阅searchCriteria$触发流执行,同时断言Error对象的message属性而非直接断言对象:

fit('should set error loading search criteria failed', () => {
  const errorMessage = 'Error getting search criteria';
  bookingService.getSearchCriteria.and.returnValue(throwError(() => new Error(errorMessage)));

  component.ngOnChanges();

  // 订阅searchCriteria$触发catchError逻辑
  component.searchCriteria$.subscribe({
    complete: () => {
      // catchError返回EMPTY,流会进入complete阶段
      component.error$.subscribe((error) => {
        expect(error?.message).toBe(errorMessage);
      });
    }
  });
});

简化写法(使用async/await + toPromise)

fit('should set error loading search criteria failed', async () => {
  const errorMessage = 'Error getting search criteria';
  bookingService.getSearchCriteria.and.returnValue(throwError(() => new Error(errorMessage)));

  component.ngOnChanges();

  // 触发searchCriteria$流执行,catchError返回EMPTY所以不会抛出错误
  await component.searchCriteria$.toPromise().catch(() => {});

  const error = await component.error$.toPromise();
  expect(error?.message).toBe(errorMessage);
});

正常分支测试成功的原因

正常分支中getSearchCriteria返回of(searchCriteria),订阅searchCriteria$时流会立即发出值,断言逻辑能直接生效;而错误分支必须触发catchError,所以必须先订阅searchCriteria$才能完成error$的赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:02:47