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

Angular中调用MsalService的AuthService单元测试报错排查

Angular单元测试「Expected a spy」错误排查与修正

你的测试步骤方向是对的,但细节上的偏差导致了报错,下面拆解问题并给出修正方案:

步骤理解的偏差点

你的逻辑框架没问题,但第2、3步的执行方式有误:

  • 不需要单独用spyOn去创建间谍,用jasmine.createSpyObj直接生成带间谍方法的模拟MsalService实例更可靠
  • 调用的应该是AuthService的login方法,而不是通过spyOn执行login

「Expected a spy」报错的核心原因

这个错误说明你在expect()里验证的对象不是一个Jasmine间谍,通常是以下情况导致:

  1. 模拟的MsalService不是间谍对象,而是普通对象或真实实例
  2. spyOn的目标对象不对,导致没正确替换成间谍
  3. 验证时引用的不是间谍方法

正确的测试代码示例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:07:13