Angular单元测试中使用NgFor时子组件未渲染问题求助
父组件单元测试中*ngFor渲染子组件失败问题排查
组件代码
父组件HTML
<app-select> <app-custom-select *ngFor="let item of searcheditem" [value]="item"></app-custom-select> </app-select>
子组件app-custom-select HTML
<div *ngIf="type != '3'"> <p>{{title}}</p> </div>
单元测试代码(原代码)
const msearcheditem: searchedModel[] = [{ title: "testsearcg",category: "0",url:"",description: "",rating:Rating.NA }, { title: "test reports",category: "0",url:"",description: "",rating:Rating.NA }]; component.recentSearches=mockRecentSearchesList; fixture.detectChanges(); flush(); component.isFocussedState=true; component.isActiveTypedState =false; fixture.detectChanges(); fixture.whenStable().then(()=>{ fixture.detectChanges(); console.log(fixture.debugElement.nativeElement); console.log(component.recentSearches); const element: DebugElement[]=fixture.query(By.css('app-custom-select')) expect(element.length).toEqual(2); // 报错,元素未找到
问题现象
- 测试断言
expect(element.length).toEqual(2)失败,提示未找到目标元素 - 打印DOM可见
<!--bindings={"ng-reflect-ng-for-of": ""}-->,说明*ngFor绑定的数据源为空
问题原因及修复方案
数据源不匹配
父组件模板中*ngFor遍历的是searcheditem,但测试代码错误赋值给了recentSearches,需修正为:component.searcheditem = msearcheditem; // 替换原有的component.recentSearches赋值异步逻辑混乱
测试混合使用whenStable()和fakeAsync/flush,应统一用fakeAsync包裹测试逻辑,确保异步操作被正确处理:it('should render 2 app-custom-select components', fakeAsync(() => { // 测试代码放在此处 flush(); // 处理所有异步任务 fixture.detectChanges(); }));元素查询方法错误
fixture.query()仅返回第一个匹配元素,要获取所有子组件需使用fixture.queryAll():const elements: DebugElement[] = fixture.queryAll(By.css('app-custom-select')); expect(elements.length).toEqual(2);
修复后的完整测试代码
it('should render 2 app-custom-select components', fakeAsync(() => { const msearcheditem: searchedModel[] = [ { title: "testsearcg", category: "0", url: "", description: "", rating: Rating.NA }, { title: "test reports", category: "0", url: "", description: "", rating: Rating.NA } ]; // 正确赋值数据源 component.searcheditem = msearcheditem; component.isFocussedState = true; component.isActiveTypedState = false; fixture.detectChanges(); flush(); // 处理所有异步任务 fixture.detectChanges(); const elements: DebugElement[] = fixture.queryAll(By.css('app-custom-select')); expect(elements.length).toEqual(2); }));
内容的提问来源于stack exchange,提问作者Balaji Narasimhan
相关产品推荐
相关产品推荐

