Angular使用Jasmine测试插值绑定动态文本时报错Expected '' to equal undefined如何解决
报错根因
你遇到的报错是两个常见的Angular单元测试误区共同导致的:
- 测试逻辑是同步执行的,
ngOnInit中发起的API请求属于异步操作,测试执行断言时,接口还没有返回结果,component.name仍为初始的undefined,模板插值渲染空字符串,所以出现Expected '' to equal undefined的报错 - 接口返回后没有手动触发变更检测,最新的
name值不会同步更新到DOM上
正确测试用例写法
首先你需要先Mock依赖的API服务,不要发起真实网络请求,再用异步工具包裹测试逻辑,完整示例如下:
第一步:Mock依赖服务(写在describe块的beforeEach里)
import { of } from 'rxjs'; // 假设你调用的API封装在YourService服务中 let yourService: jasmine.SpyObj<YourService>; beforeEach(async () => { // 创建服务的Mock对象 const serviceSpy = jasmine.createSpyObj('YourService', ['getStoreInfo']); await TestBed.configureTestingModule({ declarations: [YourComponent], // 用Mock对象替换真实服务 providers: [{ provide: YourService, useValue: serviceSpy }] }).compileComponents(); yourService = TestBed.inject(YourService) as jasmine.SpyObj<YourService>; // 预设Mock接口的返回值 yourService.getStoreInfo.and.returnValue(of({ storeName: '测试店铺名称' })); fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; });
第二步:编写异步测试用例(推荐用fakeAsync写法)
import { fakeAsync, tick } from '@angular/core/testing'; it('should check store name', fakeAsync(() => { // 第一次调用detectChanges触发ngOnInit执行 fixture.detectChanges(); // 模拟时间流逝,等待所有异步订阅执行完成,name被赋值 tick(); // 第二次调用detectChanges触发变更检测,更新DOM内容 fixture.detectChanges(); const mypara: HTMLDivElement = fixture.debugElement.nativeElement.querySelector('.ant-tag-red'); expect(mypara).toBeTruthy(); // trim去除插值可能产生的多余空格,避免匹配误差 expect(mypara.innerHTML.trim()).toEqual(component.name); }));
可选:waitForAsync写法
如果你的异步逻辑包含定时器等不适合用tick的场景,可以用whenStable等待所有异步任务完成:
import { waitForAsync } from '@angular/core/testing'; it('should check store name', waitForAsync(() => { fixture.detectChanges(); // 等待所有异步任务执行完成 fixture.whenStable().then(() => { fixture.detectChanges(); const mypara: HTMLDivElement = fixture.debugElement.nativeElement.querySelector('.ant-tag-red'); expect(mypara).toBeTruthy(); expect(mypara.innerHTML.trim()).toEqual(component.name); }); }));
内容的提问来源于stack exchange,提问作者Optimist Rohit
相关产品推荐
相关产品推荐

