Angular 12单元测试:订阅BehaviorSubject时Spy内部函数失败问题
测试失败原因与修正方案
你的测试代码存在三个关键问题导致Spy未被调用:
- Spy创建时机错误:在调用
component.ngOnInit()之后才创建Spy,此时组件已完成订阅初始化,后续调用不会被Spy捕获。 - 事件触发顺序错误:先发送事件再初始化组件订阅,组件无法捕获这次事件。
- 额外订阅冗余:无需额外订阅
myService.event,组件自身的订阅已会触发myFunction。
修正后的测试代码如下:
describe('AppComponent', () => { let event = new BehaviorSubject(false); let component: AppComponent; let fixture: ComponentFixture<AppComponent>; let myService: MyService; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [AppComponent], providers: [{ provide: MyService, useValue: { event: event } }] }).compileComponents(); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; myService = TestBed.inject(MyService); // 直接用TestBed.inject获取服务更简洁 }); it('should create', () => { expect(component).toBeTruthy(); }); it('should call myFunction when event emits true', () => { // 1. 先创建Spy,确保后续调用被捕获 const spy = spyOn(component, 'myFunction'); // 2. 初始化组件的订阅逻辑 component.ngOnInit(); // 3. 发送true事件,触发组件订阅的回调 myService.event.next(true); // 4. 验证Spy被调用 expect(spy).toHaveBeenCalled(); }); });
关键调整说明:
- 提前创建Spy:在调用
ngOnInit前就创建Spy,保证组件订阅回调中调用的myFunction是被Spy包装后的版本。 - 调整事件触发顺序:先初始化订阅,再发送事件,确保组件能捕获到事件并触发
myFunction。 - 移除冗余订阅与done回调:因为BehaviorSubject的
next是同步触发的,不需要异步done回调,直接同步验证即可。
内容的提问来源于stack exchange,提问作者e.k
相关产品推荐
相关产品推荐

