Angular 自定义验证器 FormGroup 的单元测试

Angular Unit Test for Custom Validator FormGroup

如何单元测试(此处为Jest)自定义验证器,其中有FormGroup?我看过 this question,但它大约是 FormControl

待测函数

import { FormGroup } from '@angular/forms';

/**
 * @description Validate if passwords are different.
 * @function validatePasswords
 * @param {string} passwordControlName - reference to formControlPassword of the contactForm.
 * @param {string} confirmPasswordControlName - reference to formControlConfirmPassword of the contactForm.
 * @returns {(formGroup: FormGroup) => void}
 */
export function validatePasswords(
  passwordControlName: string,
  confirmPasswordControlName: string
): (formGroup: FormGroup) => void {
  return (formGroup: FormGroup) => {
    // Get values of desired controls of the form.
    const passwordControl = formGroup.controls[passwordControlName];
    const confirmPasswordControl =
      formGroup.controls[confirmPasswordControlName];

    if (
      // Don't show the error if any different error occured in password confirmation.
      confirmPasswordControl.errors &&
      !confirmPasswordControl.errors.passwordMismatch
    ) {
      return; // Different validator shown an error, therefore return.
    }

    // Check if password and password confirmation are different.
    if (passwordControl.value !== confirmPasswordControl.value) {
      confirmPasswordControl.setErrors({ passwordMismatch: true }); // Password and confirm password are different, therefore show passwordMismatch error.
    } else {
      confirmPasswordControl.setErrors(null); // Password and confirm password are the same, therefore don't display any error.
    }
  };
}

您可以创建一个包含 2 个密码控件的测试 FormGroup,并将 validatePasswords 验证程序应用到该组:

describe('validatePasswords', () => {
  const password = 'password';
  const confirmPassword = 'confirmPassword';
  let formGroup: FormGroup;

  beforeEach(() => {
    formGroup = new FormGroup({
      [password]: new FormControl(),
      [confirmPassword]: new FormControl(),
    }, validatePasswords(password, confirmPassword));
  });

  it('should has "passwordMismatch" error if passwords do not match', () => {
    formGroup.patchValue({
      [password]: '123',
      [confirmPassword]: '321'
    });
    
    expect(formGroup.get(confirmPassword).hasError('passwordMismatch')).toBe(true);
  });
  
  it('should be valid if passwords match', () => {
    formGroup.patchValue({
      [password]: '123',
      [confirmPassword]: '123'
    });
    
    expect(formGroup.get(confirmPassword).valid).toBe(true);
  });
});