Angular中调用MsalService的AuthService单元测试报错排查
Angular单元测试「Expected a spy」错误排查与修正
你的测试步骤方向是对的,但细节上的偏差导致了报错,下面拆解问题并给出修正方案:
步骤理解的偏差点
你的逻辑框架没问题,但第2、3步的执行方式有误:
- 不需要单独用
spyOn去创建间谍,用jasmine.createSpyObj直接生成带间谍方法的模拟MsalService实例更可靠 - 调用的应该是AuthService的login方法,而不是通过
spyOn执行login
「Expected a spy」报错的核心原因
这个错误说明你在expect()里验证的对象不是一个Jasmine间谍,通常是以下情况导致:
- 模拟的MsalService不是间谍对象,而是普通对象或真实实例
spyOn的目标对象不对,导致没正确替换成间谍- 验证时引用的不是间谍方法
正确的测试代码示例
import { TestBed } from '@angular/core/testing'; import { AuthService } from './auth.service'; import { MsalService } from '@azure/msal-angular'; describe('AuthService', () => { let authService: AuthService; // 声明MsalService的间谍对象 let msalServiceSpy: jasmine.SpyObj<MsalService>; beforeEach(() => { // 创建带loginRedirect方法的间谍对象 msalServiceSpy = jasmine.createSpyObj('MsalService', ['loginRedirect']); TestBed.configureTestingModule({ providers: [ AuthService, // 用间谍对象替代真实的MsalService { provide: MsalService, useValue: msalServiceSpy } ] }); // 获取AuthService实例 authService = TestBed.inject(AuthService); }); it('should trigger msalService.loginRedirect when login is called', () => { // 调用AuthService的login方法 authService.login(); // 验证间谍的loginRedirect方法被调用 expect(msalServiceSpy.loginRedirect).toHaveBeenCalled(); }); });
关键注意事项
- 始终确保注入到AuthService的是间谍版本的MsalService,而不是真实服务
- 不要同时混用
createSpyObj和spyOn,前者已经帮你创建了间谍方法 - 验证时必须引用间谍对象的方法(比如
msalServiceSpy.loginRedirect),而不是其他对象的同名方法
内容的提问来源于stack exchange,提问作者Welp
相关产品推荐
相关产品推荐

