使用Jest测试TS类方法时如何mock内部调用的getProfileAPI函数
解决方案
核心问题说明
你当前的测试代码直接把getProfile方法替换为了mock空函数,原类方法的内部逻辑完全不会执行,自然无法触发内部的getProfileAPI调用,也不可能修改profile属性值。要测试原方法逻辑,只需要mock它依赖的外部API函数即可,不要覆盖被测试的getProfile方法本身。
方案1:全局模块mock
通过jest.mock直接mock整个api模块,所有用例都可以复用mock逻辑,适合多场景测试:
import Profile from './Profile'; // 导入要mock的API函数 import { getProfileAPI } from "./api"; // 全局mock ./api模块的所有导出内容 jest.mock("./api"); describe('Profile', () => { // 每次测试前重置状态,避免用例间互相影响 beforeEach(() => { jest.clearAllMocks(); Profile.profile = ''; }); it('接口返回数据时profile赋值正确', async () => { // 模拟接口返回内容 const mockData = '测试用户资料'; (getProfileAPI as jest.Mock).mockResolvedValue({ data: mockData }); // 直接调用原方法,不要替换为mock函数 await Profile.getProfile(); // 校验API调用符合预期 expect(getProfileAPI).toHaveBeenCalledTimes(1); // 校验profile赋值符合预期 expect(Profile.profile).toBe(mockData); }); it('接口无返回data时profile保持初始值', async () => { // 模拟接口返回无data的场景 (getProfileAPI as jest.Mock).mockResolvedValue({}); await Profile.getProfile(); expect(getProfileAPI).toHaveBeenCalledTimes(1); expect(Profile.profile).toBe(''); }); });
方案2:局部spy mock
用jest.spyOn单独mock目标API函数,不需要全局覆盖模块,适合单一场景测试:
import Profile from './Profile'; import * as apiModule from "./api"; describe('Profile', () => { it('接口返回数据时profile赋值正确', async () => { const mockData = '测试用户资料'; // 仅mock单个getProfileAPI方法 const apiSpy = jest.spyOn(apiModule, 'getProfileAPI').mockResolvedValue({ data: mockData }); await Profile.getProfile(); expect(apiSpy).toHaveBeenCalledTimes(1); expect(Profile.profile).toBe(mockData); // 测试结束恢复原方法 apiSpy.mockRestore(); }); });
注意事项
- 示例中的
as jest.Mock是为了兼容TS类型检查,避免TS识别不到mock函数的专属方法报错 - 因为你导出的是单例实例,记得在每个用例执行前重置
profile属性的初始值,避免多个用例之间数据污染 - 不要覆盖被测试的
getProfile方法本身,你要验证的就是这个方法的逻辑是否正确,覆盖后就失去了测试意义
内容的提问来源于stack exchange,提问作者ashik ahmed
相关产品推荐
相关产品推荐

