Angular单元测试:FormControl检测minLength/maxLength校验器失败
FormControl校验器hasValidator检测minLength/maxLength失败的原因及解决办法
问题根源
Validators.required是一个固定的函数实例,所以直接用hasValidator(Validators.required)时,能匹配到FormControl上挂载的同一个函数引用,测试自然通过。
但Validators.minLength(n)和Validators.maxLength(n)是工厂函数——每次调用它们,都会生成一个全新的函数实例。哪怕两次调用传入的参数完全一样,返回的函数引用也不相同。你给FormControl添加校验器时用的是第一次调用生成的函数,测试断言里又调用一次生成新函数,两者引用不匹配,所以hasValidator返回false,测试失败。
解决方案
有两种靠谱的解决方式:
方式一:复用校验器实例
提前保存工厂函数返回的校验器实例,在创建FormControl和测试断言时复用同一个引用:
it('should create input form field validators', () => { // 提前生成并保存校验器实例 const minLengthValidator = Validators.minLength(1); const maxLengthValidator = Validators.maxLength(9); const control = new FormControl<string>( '', [ Validators.required, minLengthValidator, maxLengthValidator ] ); expect(control.hasValidator(Validators.required)).toBeTruthy(); // 复用同一个实例进行断言 expect(control.hasValidator(minLengthValidator)).toBeTruthy(); expect(control.hasValidator(maxLengthValidator)).toBeTruthy(); });
方式二:通过错误信息验证校验器
不依赖函数引用,而是通过模拟输入、校验FormControl的错误信息来间接确认校验器是否生效:
it('should create input form field validators', () => { const control = new FormControl<string>( '', [ Validators.required, Validators.minLength(1), Validators.maxLength(9) ] ); // 验证required校验器 expect(control.hasValidator(Validators.required)).toBeTruthy(); // 验证minLength校验器:输入长度不足的值,检查错误 control.setValue(''); expect(control.errors?.['minlength']).toBeTruthy(); expect(control.errors?.['minlength'].requiredLength).toBe(1); // 验证maxLength校验器:输入长度超限的值,检查错误 control.setValue('1234567890'); expect(control.errors?.['maxlength']).toBeTruthy(); expect(control.errors?.['maxlength'].requiredLength).toBe(9); });
内容的提问来源于stack exchange,提问作者Cody Pritchard
相关产品推荐
相关产品推荐

