You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:54:56