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(); }); });
额外说明
- 注意业务代码中
Day.Friday的值需要确实等于5,否则即使模拟返回5,也不会进入对应分支(从你的测试期望来看,应该是符合的) - 原测试中的
expect(service.getCurrentBoardTimeIdByCurrentTime).toHaveBeenCalled()是错误的,你应该验证的是mockUtilService的方法被调用,而不是服务方法本身(因为你是直接调用它的)
为什么之前报错?
你看到的Expected 1 to be 7,是因为真实的UtilService.getHour()返回了当前实际小时(比如工作日的白天),getWeekDay()返回了当前星期,进入了其他分支返回了1,而不是你期望的7分支。
内容的提问来源于stack exchange,提问作者Kedar Udupa
相关产品推荐
相关产品推荐

