PrimeNG表格VirtualScroll单元测试创建方法及懒加载场景测试行获取为空问题求助
解决PrimeNG表格VirtualScroll懒加载单元测试中bodyRows为空的问题
我明白你在测试PrimeNG带懒加载的虚拟滚动表格时遇到的困境——查询不到渲染的行确实挺让人头疼的。结合PrimeNG的虚拟滚动和懒加载机制,咱们一步步来排查和解决这个问题:
核心原因分析
VirtualScroll + 懒加载的组合下,PrimeNG不会自动渲染所有数据:它只会渲染当前视口内的行,而且懒加载事件onLazyLoad需要主动触发,测试环境不会像真实浏览器那样自动触发滚动加载逻辑。另外,异步数据加载、变更检测时机也会影响DOM渲染结果。
具体解决步骤
1. 主动触发懒加载事件
测试环境中不会自动触发onLazyLoad,你需要手动模拟初始加载的参数并触发事件:
it('should render rows with virtual scroll and lazy load', async () => { // 先获取表格组件实例 const tableComponent = fixture.debugElement.query(By.css('.basicTable')).componentInstance; // 模拟初始懒加载请求(对应你模板里的rows=100) tableComponent.onLazyLoad.emit({ first: 0, rows: 100 }); // 等待异步数据加载完成(如果你的load方法是异步的,比如HTTP请求) await fixture.whenStable(); fixture.detectChanges(); // 此时再查询行元素 const tableEl = fixture.debugElement.query(By.css('.p-datatable-virtual-scrollable-body')); const bodyRows = tableEl.query(By.css('.p-datatable-tbody')).queryAll(By.css('tr')); console.log(bodyRows); // 现在应该能获取到渲染的行 });
2. 确保测试数据正确加载
如果你的load方法是调用外部接口,建议在测试中mock这个方法,直接注入测试数据,避免依赖外部服务:
// 在测试开始前mock load方法 spyOn(component, 'load').and.callFake((event) => { // 模拟加载对应数量的测试数据 component.cars = Array.from({ length: event.rows }, (_, index) => ({ id: event.first + index, brand: `Test Car ${event.first + index}` })); });
3. 确保虚拟滚动视口高度生效
有时候测试环境中,表格的scrollHeight可能没有正确应用,导致PrimeNG判断无需渲染行。可以手动设置元素高度:
const scrollBody = fixture.debugElement.query(By.css('.p-datatable-virtual-scrollable-body')).nativeElement; // 匹配你模板里的scrollHeight配置 scrollBody.style.height = '500px'; // 触发滚动事件(可选,帮助PrimeNG重新计算渲染范围) scrollBody.dispatchEvent(new Event('scroll')); fixture.detectChanges();
4. 修正模板中的重复配置
注意你的模板里重复写了两次[rows]="100",这可能导致属性冲突,建议删除其中一个:
<!-- 修正后的模板 --> <p-table class="basicTable" [value]="cars" [scrollable]="true" [rows]="100" scrollHeight="500px" (onLazyLoad)="load($event)" [lazy]="true" [virtualScroll]="true">
完整测试示例
it('should render virtual scroll rows with lazy load', async () => { // 1. Mock懒加载方法,注入测试数据 spyOn(component, 'load').and.callFake((event) => { component.cars = Array.from({ length: 150 }, (_, i) => ({ id: i, brand: `Car ${i}` })); }); fixture.detectChanges(); // 2. 触发初始懒加载事件 const tableComponent = fixture.debugElement.query(By.css('.basicTable')).componentInstance; tableComponent.onLazyLoad.emit({ first: 0, rows: 100 }); // 3. 等待异步操作完成并更新DOM await fixture.whenStable(); fixture.detectChanges(); // 4. 查询并断言行存在 const tableEl = fixture.debugElement.query(By.css('.p-datatable-virtual-scrollable-body')); const bodyRows = tableEl.query(By.css('.p-datatable-tbody')).queryAll(By.css('tr')); expect(bodyRows.length).toBeGreaterThan(0); });
内容的提问来源于stack exchange,提问作者F.BOU
相关产品推荐
相关产品推荐

