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

Angular组件单元测试报错:调用Service后无法读取undefined的then属性

报错原因

你当前的测试环境中,注入到组件的MyService实例的something方法没有返回Promise对象,调用后返回undefined,后续执行.then()时自然触发cannot read property 'then' of undefined报错。

解决步骤

  • 第一步:创建MyService的模拟实现,确保something方法返回Promise
    单元测试只需模拟依赖的返回结果即可,不需要引入真实的Service实现,示例如下:
// 在spec文件顶部定义模拟Service
const mockMyService = {
  // 用Jasmine的Spy方法模拟,可同时监听调用情况,返回成功的Promise
  something: jasmine.createSpy('something').and.returnValue(Promise.resolve({
    // 这里填写你需要的模拟返回数据
    code: 200,
    data: {}
  }))
  // 如果Service有其他被组件调用的方法,也可以在这里补充模拟
};

如果使用Jest作为测试框架,将Spy写法替换为something: jest.fn(() => Promise.resolve({}))即可。

  • 第二步:在TestBed的providers数组中替换真实Service为模拟实现
    修改TestBed.configureTestingModule的providers配置:
TestBed.configureTestingModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  imports: [...],
  declarations: [MyComponent],
  // 新增配置,用模拟对象替换真实Service
  providers: [
    { provide: MyService, useValue: mockMyService },
    // 其他原有provider保持不变
  ],
}).compileComponents();
  • 第三步:如果需要测试then回调内的逻辑,需要处理异步时序
    Angular测试中处理异步逻辑可以用fakeAsync + tick组合,修改你的测试用例:
import { fakeAsync, tick } from '@angular/core/testing';

it('should save and handle service response', fakeAsync(() => {
  // 触发组件方法
  component.myMethod();
  // 执行tick等待所有Promise回调执行完成
  tick();
  // 这里可以写断言,验证then回调内的逻辑是否符合预期
  // 比如验证组件的某个属性是否被正确赋值、某个方法是否被调用等
  expect(component.someProp).toEqual('预期值');
  // 也可以验证service方法是否被正确调用
  expect(mockMyService.something).toHaveBeenCalledWith(component.item);
}));

如果要测试请求失败的分支,只需要把模拟方法的返回值改成Promise.reject(new Error('模拟错误'))即可,对应测试catch回调的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:36:04