Angular+Jasmine+Karma测试报错:无未指定name属性表单控件值访问器
问题:Angular组件测试全部失败,报错"No value accessor for form control with unspecified name attribute"
此前运行正常的20个Angular组件测试,现在在Jasmine+Karma环境下全部失败,统一报错:
Error: No value accessor for form control with unspecified name attribute
报错前仅修改了组件中的一个函数,新旧函数对比:
旧函数
public isDisabledDQReviewer(): boolean { const periodicity = this.typeSettingForm.get('periodicity').value; const isDaily = periodicity === 'Diaria'; const isDisabled = !this.isRoleGMRU || isDaily; if (isDaily) { this.typeSettingForm.get('reviewer').setValue(false); } return isDisabled; }
新函数
public checkDQReviewerStatus(): void { const periodicity = this.typeSettingForm.get('periodicity').value; const isDaily = periodicity === 'Diaria'; const isMonthly = periodicity === 'Mensual'; const isDisabled = !this.isRoleGMRU || isDaily; if (isDaily) { this.typeSettingForm.get('reviewer').setValue(false); } if (isDisabled) { this.typeSettingForm.get('reviewer').disable({ emitEvent: false }); } else { this.typeSettingForm.get('reviewer').enable({ emitEvent: false }); } if (isMonthly && this.isRoleGMRU) { this.typeSettingForm.get('reviewer').enable(); } }
即使是完全不涉及该函数的测试也全部失败,例如:
it('is defined', () => { expect(testing.component).toBeDefined(); }); it('should disable reviewer if role is not GMRU', () => { testing.component.typeSettingForm.get('periodicity').setValue('Diaria'); const result = testing.component.checkDQReviewerStatus(); expect(result).toBeTruthy(); expect(testing.component.typeSettingForm.get('reviewer').value).toBe(false); });
已修改测试中对应的函数名,但问题仍未解决,需要恢复测试正常运行。
解决方案
1. 排查模板表单控件绑定问题
这个报错核心原因是模板中reviewer对应的表单控件存在绑定缺陷:
- 检查控件是否设置了
name属性,比如<input formControlName="reviewer" name="reviewer"> - 如果是自定义控件,必须实现
ControlValueAccessor接口;若测试时不想处理自定义控件,可在测试模块配置中添加NO_ERRORS_SCHEMA忽略未识别的组件/指令
2. 修复测试用例的逻辑错误
新函数checkDQReviewerStatus是void类型,无返回值,但测试中错误地接收了返回值并断言,需修改:
it('should disable reviewer if role is not GMRU', () => { testing.component.isRoleGMRU = false; testing.component.typeSettingForm.get('periodicity').setValue('Diaria'); testing.component.checkDQReviewerStatus(); expect(testing.component.typeSettingForm.get('reviewer').disabled).toBe(true); expect(testing.component.typeSettingForm.get('reviewer').value).toBe(false); });
3. 确保测试中组件完成模板初始化
如果checkDQReviewerStatus在组件初始化阶段(如ngOnInit、表单值变化订阅)就被调用,测试时需先触发模板绑定:
beforeEach(() => { fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; // 初始化表单实例 component.typeSettingForm = new FormGroup({ periodicity: new FormControl(''), reviewer: new FormControl(false) }); fixture.detectChanges(); // 触发模板与组件的绑定 });
4. 测试模块配置补全
若模板中使用了Angular表单模块,测试模块需导入ReactiveFormsModule或FormsModule:
TestBed.configureTestingModule({ declarations: [YourComponent], imports: [ReactiveFormsModule], schemas: [NO_ERRORS_SCHEMA] // 按需添加 });
内容的提问来源于stack exchange,提问作者Jennifer Yasmin
相关产品推荐
相关产品推荐

