Jasmine测试async方法报Cannot read properties of undefined (reading 'then')错误
报错原因
api.send方法的mock返回值不符合预期,甚至未被正确mock:- 若
api.send本身设计为返回Promise,你在测试中返回的Promise.resolve(of('pillars'))结构完全不匹配业务逻辑需要的格式:业务代码的then回调中需要读取返回结果的data属性,但你返回的Promise resolve后是RxJS的Observable对象,无对应属性,且如果send实际返回值为undefined时,调用.then()就会直接抛出"Cannot read properties of undefined (reading 'then')"报错。 - 若
api.send本身设计为返回RxJS Observable,Observable本身不存在then方法,直接调用.then()也会触发该报错。
- 若
- 异步测试未正确处理异步逻辑:
getPillars是async异步方法,测试中直接调用后没有等待异步任务执行完成,Jasmine在测试用例执行结束后的jasmine.onComplete阶段捕获到未处理的Promise rejection。 - 测试依赖注入不匹配:如果测试模块中没有正确将组件依赖的apiService替换为你做了spy的实例,组件实际调用的
api.send没有被mock,默认返回undefined也会触发该报错。 - 额外逻辑隐患:业务代码混用
await和.then()写法,可读性差且容易出现逻辑问题。
修复方案
1. 业务代码优化(可选但推荐)
移除await和.then()混用的写法,简化逻辑:
getPillars = async (): Promise<void> => { if (localStorage.getItem('pillars')) { this.pillars = JSON.parse(localStorage.getItem('pillars')); return; } // 如果api.send返回Promise const res = await this.api.send('Categories', 'get', filter ? { filter: filter } : {}); // 如果api.send返回Observable,需要先转Promise: // const res = await firstValueFrom(this.api.send('Categories', 'get', filter ? { filter: filter } : {})); const items = res.data.map(el => ({ id: el.id, name: el.name, type: 'Categories' })); localStorage.setItem('pillars', JSON.stringify(items)); this.pillars = items; }
2. 单元测试修复
- 调整spy返回值为符合业务预期的结构
- 测试用例改为async,调用异步方法时加await等待执行完成
- 提前清空localStorage避免命中缓存分支,不走
api.send逻辑
describe('getPillars()', () => { it('Should validate the session success', async () => { localStorage.removeItem('pillars'); // 如果api.send返回Promise,spy返回对应结构的Promise const spy1 = spyOn(apiService, 'send').and.returnValue(Promise.resolve({ data: [{id: 1, name: '测试分类'}], count: 1 })); // 如果api.send返回Observable,spy直接返回对应结构的Observable // const spy1 = spyOn(apiService, 'send').and.returnValue(of({ // data: [{id: 1, name: '测试分类'}], // count: 1 // })); await component.getPillars(); expect(spy1).toHaveBeenCalled(); }); });
同时需要确认测试模块中已经正确提供了apiService依赖,保证你spy的实例就是组件实际注入的实例。
内容的提问来源于stack exchange,提问作者David Angarita
相关产品推荐
相关产品推荐

