如何测试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
相关产品推荐
相关产品推荐

