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

如何测试Angular组件ngOnInit中subscribe内部的代码逻辑

测试Angular组件ngOnInit中selectRow$订阅的内部逻辑

要测试你ngOnInit里订阅selectRow$后的回调逻辑,核心是模拟这个可观察对象的数据流,同时验证变量赋值和方法调用的行为。下面是具体的实现步骤和测试用例:

先搭好测试基础

首先要模拟selectRowServices,用RxJS的Subject来替代原本的selectRow$——这样你就能手动控制什么时候推送测试数据。同时要mock掉loadData、loadRoles这些不需要在本次测试中验证的方法,避免干扰:

import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { YourComponent } from './your-component.component';
import { SelectRowServices } from './select-row.services';
import { Subject, of } from 'rxjs';

// 模拟SelectRow服务,用Subject实现可控的selectRow$
class MockSelectRowServices {
  selectRow$ = new Subject<any>();
}

describe('YourComponent', () => {
  let component: YourComponent;
  let fixture: ComponentFixture<YourComponent>;
  let mockSelectRowService: MockSelectRowServices;
  let loadUsuarioRolSpy: jasmine.Spy;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [YourComponent],
      providers: [
        { provide: SelectRowServices, useClass: MockSelectRowServices }
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(YourComponent);
    component = fixture.componentInstance;
    mockSelectRowService = TestBed.inject(SelectRowServices) as unknown as MockSelectRowServices;

    // Mock掉不需要测试的方法
    spyOn(component, 'loadData').and.returnValue(of(null));
    spyOn(component, 'loadRoles').and.returnValue(of(null));
    // 监听loadUsuarioRol的调用情况
    loadUsuarioRolSpy = spyOn(component, 'loadUsuarioRol').and.stub();
  });

  afterEach(() => {
    // 清理订阅,防止内存泄漏
    mockSelectRowService.selectRow$.complete();
  });
});

编写核心测试用例

1. 推送非空行数据时的行为验证

这个用例验证当selectRow$推送有效数据时,usuarioSelect被正确赋值,且loadUsuarioRol被调用:

it('should set usuarioSelect and trigger loadUsuarioRol on non-null row selection', fakeAsync(() => {
  // 触发组件初始化,执行ngOnInit
  fixture.detectChanges();

  // 准备测试数据
  const testUsuario = { id: 123, nombre: 'Aaron' };

  // 向selectRow$推送数据
  mockSelectRowService.selectRow$.next(testUsuario);
  // 等待RxJS流处理完成
  tick();
  // 触发变更检测
  fixture.detectChanges();

  // 验证变量赋值
  expect(component.usuarioSelect).toEqual(testUsuario);
  // 验证方法调用(如果loadUsuarioRol需要参数,记得加上对应断言)
  expect(loadUsuarioRolSpy).toHaveBeenCalledWith(testUsuario);
}));

2. 推送空数据时的行为验证

这个用例验证当selectRow$推送空值时,loadUsuarioRol不会被调用:

it('should NOT call loadUsuarioRol when selecting null', fakeAsync(() => {
  fixture.detectChanges();

  // 推送空值
  mockSelectRowService.selectRow$.next(null);
  tick();
  fixture.detectChanges();

  expect(component.usuarioSelect).toBeNull();
  expect(loadUsuarioRolSpy).not.toHaveBeenCalled();
}));

额外提示

  • 如果loadUsuarioRol是异步操作(比如调用HTTP接口),需要用fixture.whenStable()或者tick()等待异步完成后再做断言。
  • 确保每个测试用例都是独立的,避免不同用例之间的数据流干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:40:29