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

Angular单元测试spyOn未生效 方法调用断言失败问题

问题原因
  • mock返回值类型不匹配
    你为service.getPatientValues设置的mock返回值是of([])(发射空数组的同步Observable),但组件代码中拿到返回值后立刻执行JSON.parse(data)。JSON.parse的入参要求是JSON格式字符串,传入数组会直接抛出类型错误,导致next回调执行到此处直接中断,后续的loadPatientData调用、getMedicationValues请求都不会触发。
  • spyOn机制理解错误
    Jasmine的spyOn默认仅对方法添加调用监听,不会阻断原方法的执行逻辑,只有手动追加.and.stub()、.and.returnValue()、.and.callFake()等配置时,才会替换原方法实现。你为服务类方法添加了.and.returnValue()配置,因此服务方法不会执行原逻辑,但你对component.loadPatientData设置的spy未添加任何替换实现的配置,默认会执行原方法,这就是你添加的console日志可以正常输出的原因。
  • 遗漏必要的mock
    组件代码中在getMedicationValues的订阅回调里还调用了service.getConditionsValues,你未对该方法添加mock,即便修复前两个问题,执行到此处也会抛出异常。
修复方案

of()创建的是同步Observable,值会在订阅后立即发射,不需要使用fakeAsync、tick、flush处理异步。只需要修正mock返回值类型、补全缺失的mock即可:

it('should call getPatient from service', () => {      
  // 若不需要执行loadPatientData原逻辑,添加.and.stub()阻断原方法执行,避免副作用
  const dataSpy = spyOn(component, 'loadPatientData').and.stub();
  const medDataSpy = spyOn(component, 'loadMedicationData').and.stub();
  // mock返回值改为序列化后的JSON字符串,匹配JSON.parse的入参要求
  const patientSpy = spyOn(service, 'getPatientValues').and.returnValue(of('[]'));
  const medSpy = spyOn(service, 'getMedicationValues').and.returnValue(of('[]'));
  // 补全遗漏的服务方法mock
  const conditionSpy = spyOn(service, 'getConditionsValues').and.returnValue(of('[]'));

  component.getPatientDetails();

  expect(patientSpy).toHaveBeenCalledTimes(1);
  expect(dataSpy).toHaveBeenCalledTimes(1);
  expect(medSpy).toHaveBeenCalledTimes(1);
  expect(medDataSpy).toHaveBeenCalledTimes(1);
  expect(conditionSpy).toHaveBeenCalledTimes(1);
}); 
调试提示

遇到Observable订阅逻辑未按预期执行的情况,可以在订阅对象中添加error回调打印错误,能快速定位执行中断的原因:

this.service.getPatientValues().subscribe({
  next: (data) => {
    // 原有业务逻辑
  },
  error: (err) => console.error('订阅执行报错:', err)
})

只有当Observable存在异步延迟(比如使用了delay操作符、真实HTTP请求返回的流)时,才需要使用fakeAsync配合tick/flush控制时间流逝,完成异步逻辑的测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:48:22