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

使用Jest与Angular测试组件方法:RxJS Observable场景测试

需求与代码说明

我有一个在选择组件变更时触发的公共方法,该方法仅调用另外两个私有方法。每个私有方法会填充一个被RxJS监听的Observable变量。我需要编写测试用例,覆盖公共方法及两个私有方法:

  • 第一个测试用例:验证方法返回列表以填充变量
  • 第二个测试用例:验证catchError返回of([])的场景

这些私有方法中使用了pipe,因为我的服务已配置错误拦截器。

相关变量定义

free$: Observable<ILista[]> | null = null;
grant$: Observable<ILista[]> | null = null;

公共方法代码

listagemgeral(event: number) {
  this.disponiveis(event);
  this.concedidas(event);
}

填充free$的私有方法

private disponiveis(iduser: number) {
  this.free$ = this.service.listarDisponiveis(iduser).pipe(
    catchError(() => {
      return of([]);
    })
  );
}

填充grant$的私有方法

private concedidas(iduser: number) {
  this.grant$ = this.service.listarConcedidos(iduser).pipe(
    catchError(() => {
      return of([]);
    })
  );
}
测试用例示例

1. 验证方法返回列表填充变量

import { TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { YourComponent } from './your.component';
import { YourService } from './your.service';

describe('YourComponent', () => {
  let component: YourComponent;
  let service: jasmine.SpyObj<YourService>;
  const mockFreeList: ILista[] = [{ id: 1, name: '免费项1' }, { id: 2, name: '免费项2' }];
  const mockGrantList: ILista[] = [{ id: 3, name: '授权项1' }, { id: 4, name: '授权项2' }];

  beforeEach(() => {
    const serviceSpy = jasmine.createSpyObj('YourService', ['listarDisponiveis', 'listarConcedidos']);
    TestBed.configureTestingModule({
      providers: [{ provide: YourService, useValue: serviceSpy }]
    });
    component = TestBed.inject(YourComponent);
    service = TestBed.inject(YourService) as jasmine.SpyObj<YourService>;
  });

  it('调用listagemgeral后,应通过服务返回的列表填充free$和grant$', () => {
    // 模拟服务返回成功数据
    service.listarDisponiveis.and.returnValue(of(mockFreeList));
    service.listarConcedidos.and.returnValue(of(mockGrantList));

    // 调用公共方法
    component.listagemgeral(1);

    // 验证服务方法被正确调用
    expect(service.listarDisponiveis).toHaveBeenCalledWith(1);
    expect(service.listarConcedidos).toHaveBeenCalledWith(1);

    // 订阅Observable验证数据正确性
    component.free$.subscribe(data => {
      expect(data).toEqual(mockFreeList);
    });
    component.grant$.subscribe(data => {
      expect(data).toEqual(mockGrantList);
    });
  });
});

2. 验证catchError返回of([])的场景

import { TestBed } from '@angular/core/testing';
import { throwError, of } from 'rxjs';
import { YourComponent } from './your.component';
import { YourService } from './your.service';

describe('YourComponent', () => {
  let component: YourComponent;
  let service: jasmine.SpyObj<YourService>;

  beforeEach(() => {
    const serviceSpy = jasmine.createSpyObj('YourService', ['listarDisponiveis', 'listarConcedidos']);
    TestBed.configureTestingModule({
      providers: [{ provide: YourService, useValue: serviceSpy }]
    });
    component = TestBed.inject(YourComponent);
    service = TestBed.inject(YourService) as jasmine.SpyObj<YourService>;
  });

  it('服务调用失败时,disponiveis方法应返回空数组', () => {
    // 模拟服务抛出错误
    service.listarDisponiveis.and.returnValue(throwError(() => new Error('请求失败')));

    // 调用私有方法(测试场景下通过方括号语法访问私有成员)
    component['disponiveis'](1);

    // 订阅验证错误处理后的结果
    component.free$.subscribe(data => {
      expect(data).toEqual([]);
    });
  });

  it('服务调用失败时,concedidas方法应返回空数组', () => {
    service.listarConcedidos.and.returnValue(throwError(() => new Error('请求失败')));

    component['concedidas'](1);

    component.grant$.subscribe(data => {
      expect(data).toEqual([]);
    });
  });
});

注:测试私有方法时,使用TypeScript方括号语法component['disponiveis']访问私有成员是测试场景下的常见做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:25:02