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

如何在Angular Jasmine测试中模拟History?解决空值读取报错

解决Angular Jasmine测试中History.state为null的报错问题

问题

编写Angular组件测试时出现报错:TypeError: Cannot read properties of null (reading 'data'),原因是组件在ngOnInit中直接访问history.state.data,但测试环境中history.state默认是null。

组件核心触发代码

create-organization.component.ts中引发错误的逻辑:

ngOnInit(): void {
  this.journeyService.clearData()
  const historyState = history.state.data ? history.state.data.data : null;
  if (historyState) {
    // 数据处理逻辑
  }
}

解决方案

方案1:给组件添加空值保护(推荐)

通过可选链操作符?.和空值合并运算符??增强代码健壮性,避免空指针错误:

ngOnInit(): void {
  this.journeyService.clearData()
  // 多层空值检查,防止history.state或其子属性为null时触发报错
  const historyState = history.state?.data?.data ?? null;
  if (historyState) {
    const createOrganizationData: CreateOrganizationModel = {
      basic: historyState.data.basic,
      organizationalContact: historyState.data.organizationalContact,
      extraDetails: historyState.data.extraDetails,
    };
    const journeyData = { ...createOrganizationData, isEdit: true };
    this.journeyService.setData(journeyData);
  }
}

方案2:在测试中模拟History.state

直接修改全局history对象,模拟所需的状态值:

模拟空状态(基础测试场景)

修改create-organization.component.spec.ts的beforeEach块:

beforeEach(async () => {
  // 模拟history.state为空对象,避免访问null的属性
  Object.defineProperty(window.history, 'state', {
    value: {},
    writable: true
  });

  await TestBed.configureTestingModule({
    imports: [RouterTestingModule],
    declarations: [CreateOrganizationComponent],
    providers: [
      { provide: NavigationService, useValue: getNavigationServiceSpyObj() },
      { provide: SpinnerService, useValue: getSpinnerServiceSpyObj() },
      { provide: JourneyService, useValue: getJourneyServiceSpyObj() },
      { provide: TerritoryService, useValue: getTerritoryServiceSpyObj() },
      { provide: HttpClient, useValue: getHttpClientSpyObj() },
    ],
  }).compileComponents();

  fixture = TestBed.createComponent(CreateOrganizationComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});

模拟带数据的状态(验证数据加载逻辑)

添加单独测试用例,模拟有业务数据的场景:

it('should load and process data from history state', () => {
  // 模拟包含业务数据的history.state结构
  Object.defineProperty(window.history, 'state', {
    value: {
      data: {
        data: {
          basic: { orgName: 'Demo Organization' },
          organizationalContact: { contactEmail: 'demo@org.com' },
          extraDetails: { description: 'Test description' }
        }
      }
    },
    writable: true
  });

  // 重新触发组件初始化
  fixture.detectChanges();

  // 验证数据是否正确传递给journeyService
  const journeyService = TestBed.inject(JourneyService);
  expect(journeyService.setData).toHaveBeenCalledWith(jasmine.objectContaining({
    isEdit: true,
    basic: { orgName: 'Demo Organization' }
  }));
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:55:42