Angular 12 input事件全局过滤单元测试报nativeElement空错误如何解决
问题根因
两个报错本质是同一个问题:fixture.debugElement.query(By.css('.globalFilter'))返回了null,测试代码找不到页面上的全局筛选输入框元素。你第二个尝试的测试用例本身还有两处逻辑错误:事件名写为不存在的put,且spy的组件方法globalFilter不存在(你组件里的方法叫filterGlobal,而且模板里根本没调用这个方法,直接绑定的是p-table实例的filterGlobal)。
修复步骤
1. 测试模块导入PrimeNG依赖
你用到了p-table和pInputText指令,测试环境如果没导入对应的模块,指令不会渲染内部的ng-template内容,自然找不到输入框。在TestBed.configureTestingModule的配置中补全导入:
import { TableModule } from 'primeng/table'; import { InputTextModule } from 'primeng/inputtext'; import { CommonModule } from '@angular/common'; TestBed.configureTestingModule({ imports: [ CommonModule, TableModule, InputTextModule, // 其他你业务里用到的模块 ], declarations: [HomeComponent] }).compileComponents();
2. 提前初始化组件输入数据
你p-table绑定了[cols]和[cars]两个输入属性,测试前必须给这两个属性赋值,否则p-table不会渲染caption部分的筛选框:
it('should use global filter and show 1 items', fakeAsync(() => { fixture = TestBed.createComponent(HomeComponent); app = fixture.componentInstance; // 模拟组件正常运行的输入数据 app.cols = [ {field: 'brand', header: '品牌', filterMatchMode: 'contains'}, // 其他列配置和你业务代码保持一致 ]; app.cars = [ {brand: 'dsad231ff', /* 其他字段 */}, {brand: '测试其他值', /* 其他字段 */} ]; fixture.detectChanges(); // 触发第一次渲染 // 可选兜底:用原生DOM查询,兼容指令渲染后的类名变化 const globalFilter = fixture.nativeElement.querySelector('.globalFilter'); expect(globalFilter).toBeTruthy('找不到全局筛选输入框'); // 提前校验元素存在 globalFilter.value = "dsad231ff"; globalFilter.dispatchEvent(new Event("input")); tick(500); // PrimeNG筛选默认有防抖,时间可以适当调大 fixture.detectChanges(); const bodyRows = fixture.nativeElement.querySelectorAll('.p-datatable-tbody tr'); expect(bodyRows.length).toEqual(1); }));
3. 可选:用async模式代替fakeAsync
如果fakeAsync模式下仍然有异步时序问题,可以换async+whenStable的写法,等所有异步操作完成后再断言:
it('should use global filter and show 1 items', async(() => { fixture = TestBed.createComponent(HomeComponent); app = fixture.componentInstance; app.cols = [...]; app.cars = [...]; fixture.detectChanges(); const globalFilter = fixture.nativeElement.querySelector('.globalFilter'); globalFilter.value = "dsad231ff"; globalFilter.dispatchEvent(new Event("input")); fixture.whenStable().then(() => { fixture.detectChanges(); const bodyRows = fixture.nativeElement.querySelectorAll('.p-datatable-tbody tr'); expect(bodyRows.length).toEqual(1); }); }));
内容的提问来源于stack exchange,提问作者itgeek
相关产品推荐
相关产品推荐

