Angular单元测试Mock Promise出错:getOut返回undefined问题排查
解决Angular单元测试中Mock Promise返回值的问题
我来帮你搞定这个Promise mock的问题!你当前的写法太绕了,手动模拟then方法完全没必要——这正是导致你出现ReferenceError和返回undefined的核心原因:你构造的不是一个标准的Promise对象,只是个带then方法的普通对象,和Angular代码预期的Promise不兼容。
下面给你几种简单且正确的Mock方式,直接套用就行:
方式1:返回已resolved的空Promise(适合无特定返回值的场景)
如果你的checkSortCfg不需要依赖getOut的具体返回数据,直接返回一个空的resolved Promise即可:
sortApiServiceCallSpy = jasmine.createSpyObj("SortApi", ["getOut"]); // 直接返回符合类型的resolved Promise sortApiServiceCallSpy.getOut.and.returnValue(Promise.resolve([]));
方式2:返回带测试数据的Promise(模拟真实API返回)
如果checkSortCfg逻辑需要用到getOut返回的字符串数组,就用这种方式模拟真实数据:
sortApiServiceCallSpy = jasmine.createSpyObj("SortApi", ["getOut"]); // 构造模拟的API返回数据 const mockSortConfigs: string[] = ["sort-device-1", "sort-device-2", "sort-device-3"]; sortApiServiceCallSpy.getOut.and.returnValue(Promise.resolve(mockSortConfigs));
方式3:模拟API调用失败(测试错误分支)
如果要测试checkSortCfg的错误处理逻辑,就返回一个rejected的Promise:
sortApiServiceCallSpy = jasmine.createSpyObj("SortApi", ["getOut"]); sortApiServiceCallSpy.getOut.and.returnValue(Promise.reject(new Error("获取排序配置失败")));
完整测试套件示例
给你一个整合了mock逻辑的完整Angular服务测试示例,你可以直接参考调整:
import { TestBed } from '@angular/core/testing'; import { YourTargetService } from './your-target.service'; // 替换成你的服务类 import { SortApiService } from './sort-api.service'; describe('YourTargetService', () => { let service: YourTargetService; let sortApiSpy: jasmine.SpyObj<SortApiService>; beforeEach(() => { // 创建SortApiService的spy对象 const spy = jasmine.createSpyObj('SortApiService', ['getOut']); TestBed.configureTestingModule({ providers: [ YourTargetService, // 用spy替换真实的SortApiService { provide: SortApiService, useValue: spy } ] }); service = TestBed.inject(YourTargetService); sortApiSpy = TestBed.inject(SortApiService) as jasmine.SpyObj<SortApiService>; }); it('should execute checkSortCfg successfully', async () => { // 设置mock返回值 const mockData = ["config-a", "config-b"]; sortApiSpy.getOut.and.returnValue(Promise.resolve(mockData)); // 调用待测试方法 await service.checkSortCfg(); // 验证getOut是否被调用 expect(sortApiSpy.getOut).toHaveBeenCalled(); // 这里可以添加更多针对checkSortCfg业务逻辑的断言 }); });
本质上,你的原写法错误在于没有返回标准Promise对象,Angular代码里的promise = self.sortApiSvc.getOut()拿到的不是真正的Promise,后续的链式调用或await处理自然会出问题。而用Promise.resolve()/Promise.reject()返回的是标准Promise,完全符合代码的预期。
内容的提问来源于stack exchange,提问作者GPGVM
相关产品推荐
相关产品推荐

