Angular单元测试:继承组件中父类Observable未定义致报错
问题描述
ComponentA 继承自 ComponentB,单元测试中父类 ComponentB 定义的 storeObservable 始终为 undefined,调用 subscribe 时抛出错误:
TypeError: Cannot read property 'subscribe' of undefined
相关代码
父类 ComponentB 关键代码
this.storeObservable = this.store.select(selectCandidateState);
ComponentA 关键代码
export class ComponentA extends ComponentB implements OnInit, OnDestroy { ngOnInit() { super.ngOnInit(); this.storeObservable.subscribe((candidateState) => { this.candidateSkills = candidateState.skills; this.unsavedChanges = false; }); } }
单元测试代码
let shallow: Shallow<ComponentA>; beforeEach(() => { const actions$ = new Observable(); const services = [Store]; const mockedServices = [ConfigCzarServiceMock({ test: 'property' })]; shallow = createShallowComponent( ComponentA, ProfileModule, [ComponentB], [], services, mockedServices, ); });
解决方案
问题出在测试中未正确模拟父类依赖的 Store,导致 storeObservable 未初始化。按以下步骤修复:
模拟 Store 实例并返回有效 Observable
创建 Store 的模拟对象,让select方法返回一个包含测试数据的 Observable,确保父类能初始化storeObservable:// 需导入 rxjs 的 of 操作符 import { of } from 'rxjs'; let mockStore: jasmine.SpyObj<Store>; beforeEach(() => { // 创建 Store 模拟,mock select 方法 mockStore = jasmine.createSpyObj('Store', ['select']); // 返回包含测试数据的 Observable,匹配业务逻辑所需结构 mockStore.select.and.returnValue(of({ skills: [] })); const actions$ = new Observable(); const services = []; const mockedServices = [ ConfigCzarServiceMock({ test: 'property' }), { provide: Store, useValue: mockStore } // 注入模拟的 Store ]; shallow = createShallowComponent( ComponentA, ProfileModule, [ComponentB], [], services, mockedServices, ); });确认父类生命周期方法执行
确保 ComponentB 的ngOnInit中确实完成了storeObservable的赋值,且 ComponentA 的ngOnInit中调用了super.ngOnInit()(你的代码已满足此要求)。可选:验证模拟调用
添加测试用例验证 Store 的 select 方法是否被正确调用:it('should initialize storeObservable via parent class', async () => { await shallow.render(); expect(mockStore.select).toHaveBeenCalledWith(selectCandidateState); });
内容的提问来源于stack exchange,提问作者ABGR
相关产品推荐
相关产品推荐

