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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:10:26