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
相关产品推荐
相关产品推荐

