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

Angular单元测试SpyOn未生效:调用方法实际实现而非模拟返回

解决Angular单元测试中模拟服务未生效的问题

你的问题核心在于:你创建了UtilService的Spy对象,但没有让Angular的测试床(TestBed)使用这个模拟实例,而是依然注入了真实的UtilService,所以测试时BoardSharedService调用的是真实方法的返回值,自然得不到你期望的结果。

原测试代码的问题分析

在你的测试代码里:

  • beforeEach中配置providers: [BoardSharedService, UtilService],这会让TestBed注入真实的UtilService实例
  • 后面创建的getHourSpy和getWeekDaySpy只是独立的Spy对象,并没有和TestBed中的依赖注入系统关联起来,所以BoardSharedService依赖的还是真实的服务,你的模拟返回值根本没被用到

修复步骤及代码

我们需要创建一个包含两个目标方法的UtilService模拟对象,然后告诉TestBed用这个模拟对象替换真实的服务。以下是修改后的完整测试代码:

describe('BoardSharedService', () => { 
  let service: BoardSharedService;
  // 声明模拟的UtilService
  let mockUtilService: jasmine.SpyObj<UtilService>;

  beforeEach(() => {
    // 创建包含getHour和getWeekDay方法的Spy对象
    mockUtilService = jasmine.createSpyObj('UtilService', ['getHour', 'getWeekDay']);

    TestBed.configureTestingModule({
      providers: [
        BoardSharedService,
        // 用模拟对象替换真实的UtilService
        { provide: UtilService, useValue: mockUtilService }
      ]
    });
    // 获取BoardSharedService实例
    service = TestBed.inject(BoardSharedService);
  });

  it('should return 7 when current hour is outside 6-17 and weekday is Friday', () => {
    // 设置模拟方法的返回值
    mockUtilService.getHour.and.returnValue(2);
    mockUtilService.getWeekDay.and.returnValue(5);

    const result = service.getCurrentBoardTimeIdByCurrentTime();
    // 验证返回值符合预期
    expect(result).toBe(7);
    // 验证模拟方法被调用过
    expect(mockUtilService.getHour).toHaveBeenCalled();
    expect(mockUtilService.getWeekDay).toHaveBeenCalled();
  });
});

额外说明

  1. 注意业务代码中Day.Friday的值需要确实等于5,否则即使模拟返回5,也不会进入对应分支(从你的测试期望来看,应该是符合的)
  2. 原测试中的expect(service.getCurrentBoardTimeIdByCurrentTime).toHaveBeenCalled()是错误的,你应该验证的是mockUtilService的方法被调用,而不是服务方法本身(因为你是直接调用它的)

为什么之前报错?

你看到的Expected 1 to be 7,是因为真实的UtilService.getHour()返回了当前实际小时(比如工作日的白天),getWeekDay()返回了当前星期,进入了其他分支返回了1,而不是你期望的7分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:56:18