mercredi 13 mars 2019

Test a Reactive Form field that has a custom validator in Angular

I am trying to test the valid state of a custom validated field on a Reactive form.

My component is as below:

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { ageRangeValidator } from './age-range-validator.directive';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Reactive Forms';
  genders = ['Female', 'Male'];

  constructor(private fb: FormBuilder) { }

  userForm = this.fb.group({
    firstname: ['', [Validators.required, Validators.minLength(2)]],
    surname: ['', [Validators.required, Validators.minLength(2)]],
    address: this.fb.group({
      houseNo: [''],
      street: [''],
      city: [''],
      postcode: ['']
    }),
    // Section 1
    // age: [null, Validators.min(18)],
    // Section 2 - using a Custom validator
    age: [null, ageRangeValidator(18, 68)],
    gender: ['']
  });
}

The ageRangeValidator function is as follows - this has been fully tested and works:

import { AbstractControl, ValidatorFn } from '@angular/forms';

export function ageRangeValidator(min: number, max: number): ValidatorFn {
  return (control: AbstractControl): { [key: string]: boolean } | null => {
    if ((!isNaN(control.value) && control.value) && control.value > min && control.value < max) {
      return { 'ageRange': true };
    }
    return null;
  };
}

I have a test for the App component set up as below where I set the value of the age field and then test to see if it is valid - the test returns validity to be false:

import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { DebugElement } from '@angular/core';

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let app: AppComponent;


  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports: [ReactiveFormsModule]
    }).compileComponents();

  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    app = fixture.debugElement.componentInstance;
    fixture.detectChanges();
  });
  
  describe(`Test the validity of the fields`, () => {
    it(`should return true if a value of 18 or more AND 68 or LESS is supplied (as string or number)`, () => {
      const age = app.userForm.controls['age'];
      age.setValue(42);
      expect(age.valid).toBeTruthy();
    });
  });

I expect that the solution will require the ageRangeValidator function to be hooked up to the test component in some way but I can't work out how - can anyone please suggest a way I could do this (if it is possible at all)?

Ultimately, I'm trying to test the validity of the form to ensure that it can be submitted when all required fields are valid.

Aucun commentaire:

Enregistrer un commentaire