单元测试spec.ts无法获取.ts组件中已填充的allAppointment数组如何解决
问题原因
你拿到空数组是因为getAppointments方法里调用dashboardService.getAllPatients()是异步请求,subscribe的回调函数要等请求返回才会执行给allAppointment赋值。你当前的测试是同步执行断言的,这时候回调还没触发,数组自然是空的。
解决步骤
- 第一步:在测试用例中mock DashboardService,避免调用真实后端接口,同时可以自己控制返回的测试数据
// 先导入rxjs的of操作符,用于生成mock可观察对象 import { of } from 'rxjs'; // 定义mock的测试预约数据 const mockAppointments = [ {id:1, title:'测试预约1'}, {id:2, title:'测试预约2'} ] as AppointmentModel[]; // 生成mock服务对象 const mockDashboardService = jasmine.createSpyObj('DashboardService', ['getAllPatients']); mockDashboardService.getAllPatients.and.returnValue(of(mockAppointments)); // 在TestBed配置中替换真实服务为mock服务 TestBed.configureTestingModule({ declarations: [DashboardComponent], providers: [ { provide: DashboardService, useValue: mockDashboardService } ] })
- 第二步:使用Angular异步测试工具,等待异步任务执行完成后再断言,推荐使用
fakeAsync + tick方案
// 导入测试工具 import { fakeAsync, tick } from '@angular/core/testing'; beforeEach(() => { fixture = TestBed.createComponent(DashboardComponent); component = fixture.componentInstance; fixture.detectChanges(); // 第一次detectChanges会触发ngOnInit,已经自动调用getAppointments,不需要手动重复调用 }); it('should create', () => { expect(component).toBeTruthy(); }); it("all appointments added correctly", fakeAsync(() => { tick(); // 等待所有异步任务(包含rxjs订阅回调)执行完成 expect(component.allAppointment.length).toEqual(2); // 和你mock的数组长度一致 expect(component.allAppointment).toEqual(mockAppointments); // 可进一步校验内容是否匹配 }));
如果你更习惯用waitForAsync方案,也可以替换为以下写法:
import { waitForAsync } from '@angular/core/testing'; it("all appointments added correctly", waitForAsync(() => { fixture.whenStable().then(() => { expect(component.allAppointment.length).toEqual(2); }) }));
- 优化提示:你当前
beforeEach里手动调用了component.getAppointments(),而fixture.detectChanges()触发ngOnInit时已经执行过一次该方法,重复调用会导致数组重复插入数据,建议删掉手动调用的冗余代码。 - 拼写校验:注意你提问中写的
allAppointments和实际组件里定义的属性名allAppointment差了后缀s,避免拼写错误导致的取值异常。
内容的提问来源于stack exchange,提问作者Pratish Dewangan
相关产品推荐
相关产品推荐

