Jest.js Angular -验证FormControl在单元测试中是否有Validator失败

bt1cpqcv  于 12个月前  发布在  Jest
关注(0)|答案(2)|浏览(181)

我正在为一个接收FormControl的服务编写单元测试,选项指定应该添加并返回哪些验证器。
我的单元测试应该验证FormControl是否具有所需的minLength和maxLength验证器,但是,它总是无法检查是否存在最小或最大长度验证器。
在调试时,我可以验证它的数组中有3个验证器。
为了简洁起见,我只在一个测试函数中编写了它:

it('should create input form field validators', () => {
    const control = new FormControl<string>(
      '',
      [
        Validators.required,
        Validators.minLength(1),
        Validators.maxLength(9)
      ]
    );

    expect(control.hasValidator(Validators.required)).toBeTruthy();

    // the next two lines should pass as true, but both fail.
    expect(control.hasValidator(Validators.minLength(1))).toBeTruthy();
    expect(control.hasValidator(Validators.maxLength(9))).toBeTruthy()
  });

字符串
这应该是非常直接的。我在这里遗漏了什么吗?为什么Required的逻辑通过了,但其他的逻辑失败了?

icnyk63a

icnyk63a1#

看起来像一个参考问题:
Angular文档中的示例代码:https://angular.io/api/forms/AbstractControl#reference-to-a-validatorfn-1

// Reference to the RequiredValidator
const ctrl = new FormControl<number | null>(0, Validators.required);
expect(ctrl.hasValidator(Validators.required)).toEqual(true)

// Reference to anonymous function inside MinValidator
const minValidator = Validators.min(3);
const ctrl = new FormControl<number | null>(0, minValidator);
expect(ctrl.hasValidator(minValidator)).toEqual(true)
expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)

字符串
所以你的代码应该是这样的:

it('should create input form field validators', () => {
  const minValidator = Validators.minLength(1);
  const maxValidator = Validators.maxLength(9);

  const control = new FormControl<string>('', [Validators.required, minValidator, maxValidator]);

  expect(control.hasValidator(Validators.required)).toBeTruthy();
  expect(control.hasValidator(minValidator)).toBeTruthy();
  expect(control.hasValidator(maxValidator)).toBeTruthy();
});

f87krz0w

f87krz0w2#

正如Schrader回答的那样,问题是由于我如何创建服务而引起的构造函数/引用问题。
我有一个工厂服务,我可以重用它来创建验证器并将其添加到FormControls中,如下所示:

private buildForm(): FormGroup {
    return new FormGroup({
      myControl: this.formControlFactory.buildFormControl(myControlInterface),
      ...
    });
  }

字符串
FormControlFactory服务是这样的:

@Injectable({providedIn: 'root'})
export class FormControlValidatorFactory {

  buildFormControl(formField: IInputFormField): FormControl {
    const control = new FormControl<string>('');
    if (formField.validators?.required) this.getRequiredValidator(control);
    if (formField.validators?.length) this.getLengthValidators(control, formField);
    if (formField.validators?.number) this.getNumberValidators(control, formField);
    if (formField.validators?.pattern) this.getPatternValidator(control, formField);
    return control;
  }

  ...

  private getLengthValidators(control: FormControl, formField: IInputFormField): void {
    if (formField.validatorValues?.minLength) 
      control.addValidators(Validators.minLength(formField.validatorValues.minLength));
    
    if (formField.validatorValues?.maxLength) 
      control.addValidators(Validators.maxLength(formField.validatorValues.maxLength));
  }
  ...
}


该服务中的方法查看接口并基于布尔值添加验证器,因此,在单元测试中,我无法访问添加的实际验证器,我必须以不同的方式测试服务功能。
为了验证是否添加了正确的验证器,我选择进行如下单元测试:

it('should have minLength validator and error', () => {
    inputFormField.validators = { length: true };
    inputFormField.validatorValues = { minLength: 3 };
    inputControl = service.buildFormControl(inputFormField);

    inputControl.setValue('x');
    const errors = JSON.parse(JSON.stringify(inputControl.errors));

    expect(inputControl.invalid).toEqual(true);
    expect(errors.minlength).toBeTruthy();
  });


为每个验证器场景编写类似的单元测试,直到完全覆盖。

相关问题