Angular12响应式表单Jasmine测试querySelector null报错如何解决
问题原因分析
- 第一个报错原因:form标签未设置
id="myForm",使用querySelector('#myForm')无法匹配到元素,返回null后调用querySelector触发空指针 - 第二个报错原因:选择id为numeroDeIndentificacion的元素时遗漏了id选择器的
#前缀,querySelector('numeroDeIndentificacion')会匹配标签名,自然返回null,赋值value时报错 - 隐藏问题:测试模块未导入
ReactiveFormsModule,响应式表单相关指令无法识别,表单视图渲染异常 - 校验逻辑匹配问题:你给输入框赋值为
"0",而表单控件配置了Validators.minLength(4),此时表单本身就是无效状态,断言isLogginFormValid为真必然失败 - 拼写一致性问题:注意你代码中控件名为
numeroDeIndentificacion,不要误写为带t的Identificacion,避免拿不到控件的情况
修改方案
第一步:调整测试模块配置
先在测试文件顶部导入响应式表单模块,再添加到TestBed配置中:
import { ReactiveFormsModule } from '@angular/forms'; import { of } from 'rxjs'; // 测试异步服务返回需要用到 // 调整configureTestingModule配置 await TestBed.configureTestingModule({ declarations: [ ConsultarColaboradorComponent ], imports: [ HttpClientTestingModule, ReactiveFormsModule ] }) .compileComponents();
第二步:修正测试用例代码
以下是覆盖表单校验、提交逻辑的完整测试用例,支持直接使用:
// 测试表单字段校验逻辑 it('should validate numeroDeIndentificacion field correctly', () => { // 直接通过id获取输入框元素,不需要先查form const inputElement: HTMLInputElement = fixture.debugElement.nativeElement.querySelector('#numeroDeIndentificacion'); const control = component.myForm.get('numeroDeIndentificacion'); // 场景1:空值必填校验 inputElement.value = ''; inputElement.dispatchEvent(new Event('input')); fixture.detectChanges(); expect(control.errors.required).toBeTruthy(); expect(component.myForm.invalid).toBeTrue(); // 场景2:小于最小长度4位校验 inputElement.value = '123'; inputElement.dispatchEvent(new Event('input')); fixture.detectChanges(); expect(control.errors.minlength).toBeTruthy(); expect(component.myForm.invalid).toBeTrue(); // 场景3:超出最大长度30位校验 inputElement.value = '1234567890123456789012345678901'; inputElement.dispatchEvent(new Event('input')); fixture.detectChanges(); expect(control.errors.maxlength).toBeTruthy(); expect(component.myForm.invalid).toBeTrue(); // 场景4:合法值校验 inputElement.value = '12345'; inputElement.dispatchEvent(new Event('input')); fixture.detectChanges(); expect(control.errors).toBeNull(); expect(component.myForm.valid).toBeTrue(); }); // 测试表单提交逻辑 it('should trigger data query when form is valid and submitted', () => { // 直接给表单赋合法值,也可以用上面操作DOM的方式模拟用户输入 component.myForm.patchValue({numeroDeIndentificacion: 12345}); const dataService = TestBed.inject(DataService); // 模拟服务返回结果 const mockColaborador = { numeroDeIndentificacion: 12345, nombres: '测试', apellidos: '用户' // 其他字段按你Colaborador接口的定义补充完整即可 } as Colaborador; spyOn(dataService, 'ConsultarColaboradorPorIdentificacion').and.returnValue(of(mockColaborador)); // 触发表单提交 component.onSubmit(); expect(dataService.ConsultarColaboradorPorIdentificacion).toHaveBeenCalledWith(12345); expect(component.submitted).toBeTrue(); expect(component.items).toEqual(mockColaborador); });
如果仅需要测试表单逻辑不需要模拟用户输入,也可以直接调用control.setValue()方法修改表单值,无需操作DOM元素,测试效率更高。
内容的提问来源于stack exchange,提问作者Jhon Hernández
相关产品推荐
相关产品推荐

