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

Jasmine测试subscribe回调内方法调用报Expected 0 to be 1如何解决

问题根因

测试失败由两个问题导致:

  • 间谍挂载时机不对:of(null)是同步发射值的Observable,你在调用component.save()之后才初始化testMethod的监听间谍。save()执行时subscribe回调会同步触发,直接调用原始的testMethod,此时间谍还未生效,完全捕获不到这次调用。
  • 缺少异步时序保障:如果upsert返回的是异步流(比如带delay操作符、真实HTTP请求的响应流),即使调整了间谍顺序,断言逻辑也会先于subscribe回调执行,同样会统计到0次调用。
修复方案

按照以下两点调整测试用例即可:

  • 将testMethod的间谍注册逻辑移到component.save()调用之前,保证方法执行时间谍已经处于监听状态。
  • 使用@angular/core/testing提供的fakeAsync和tick工具包裹测试逻辑,强制同步所有待执行的异步任务,彻底规避时序问题。

修复后的完整测试用例代码:

import { of } from 'rxjs';
import { fakeAsync, tick } from '@angular/core/testing';

it('should call testMethod()', fakeAsync(() => {
  // 提前注册间谍,追加.and.stub()可以阻断testMethod原有逻辑执行,避免无关逻辑干扰测试结果
  const testMethodSpy = spyOn(component, 'testMethod').and.stub();
  // 配置mock服务的返回值
  mockTestService.upsert.and.returnValue(of(null));
  // 执行待测试的save方法
  component.save();
  // 推进所有异步任务执行完成
  tick();
  // 断言testMethod被调用了1次
  expect(testMethodSpy.calls.count()).toBe(1);
}));

注意:如果testMethod本身逻辑简单、无外部依赖,执行不会产生副作用,也可以省略.and.stub(),保留方法原有逻辑执行。使用fakeAsync是兼容同步、异步Observable的通用写法,后续即使修改upsert返回流的逻辑,测试也不会因为时序问题意外失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:36:21