Angular组件Jasmine测试报错:预期spy updateValueAndValidity被调用
问题原因分析
- 错误的测试期望:你删除了索引0的控件(也就是
control1),之后forEach遍历的是删除后剩下的控件(仅原来的control2),所以control1的updateValueAndValidity根本不会被调用,测试里却期望它被触发,这必然报错。 - 组件方法的不规范操作:直接对
this.rules.controls执行splice不是Angular FormArray的正确用法。FormArray提供了专门的removeAt方法来移除控件,直接操作controls数组可能导致FormArray内部状态和控件列表不同步,进而影响有效性更新逻辑的一致性。
修复方案
1. 修正组件的deleteRule方法
改用FormArray内置的removeAt方法替代直接操作控件数组,确保FormArray状态正确:
deleteRule(index: number): void { this.rules = this.formGroup.get('rules') as FormArray; if (this.rules.length > 1) { // 使用FormArray官方API移除控件 this.rules.removeAt(index); this.rules.controls.forEach(control => control.updateValueAndValidity()); } }
2. 修正测试用例的逻辑与期望
删除后仅剩下原control2,只需验证它的方法被调用,同时调整测试逻辑避免无效赋值:
it('should update validity of remaining controls after deleting a rule', () => { let rules: FormArray = component.formGroup.get('rules') as FormArray; rules.push(component.createRule()); rules.push(component.createRule()); const control2 = rules.at(1); spyOn(control2, 'updateValueAndValidity').and.callThrough(); component.deleteRule(0); // 仅验证剩余控件的方法被调用 expect(control2.updateValueAndValidity).toHaveBeenCalled(); // 可选:验证控件确实被移除 expect(rules.length).toBe(1); });
内容的提问来源于stack exchange,提问作者CJe
相关产品推荐
相关产品推荐

