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

Angular+Karma/Jasmine使用spyOn时出现Expected a spy, but got Function错误

问题原因与解决方案

错误根源

Expected a spy, but got Function 错误说明你断言时的 component.login 并非Jasmine spy对象,核心问题是**spyOn 的执行时机晚于 login 方法的调用时机**——当 login 被触发时,spy还未完成对原始函数的包装,实际执行的是未被监听的原始函数,导致断言无法识别其为spy。

你的代码问题点

你先触发了 authState$.next({ isAuthenticated: false }),再创建spy,若authState的变化会立即触发 login 方法,此时spy还未生效,自然无法捕获到调用行为。

修正方案

1. 调整spy创建顺序

优先创建spy,再触发状态变化,确保 login 被调用时已被spy监听:

fit('should redirect to login because user is not auth', async() => {
  // 先创建spy,确保监听早于方法执行
  spyOn(component, 'login').and.callThrough();
  
  // 触发状态变化,此时login调用会被spy捕获
  authState$.next({ isAuthenticated: false });
  
  // 使用await简化异步处理(替代then写法)
  await fixture.whenStable();
  
  // 断言spy被调用
  expect(component.login).toHaveBeenCalled();
});

2. 组件初始化场景的额外处理

如果 login 是在组件初始化(如ngOnInit)时通过监听authState$触发的,需确保spy创建在fixture.detectChanges()之前:

fit('should redirect to login because user is not auth', async() => {
  // 先创建spy
  spyOn(component, 'login').and.callThrough();
  
  // 触发组件初始化,此时authState监听会触发login
  fixture.detectChanges();
  
  await fixture.whenStable();
  
  expect(component.login).toHaveBeenCalled();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:57:09