Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a unit test case for a custom validator for angular reactive forms?

I have a custom model-driven form validator to validate maximum text length

export function maxTextLength(length: string) {
  return function (control: FormControl) {
    const maxLenghtAllowed: number = +length;
    let value: string = control.value;
    if (value !== '' && value != null) {
      value = value.trim();
    }

    if (value != null && value.length > maxLenghtAllowed) {
      return { maxTextLength: true };
    }else {
      return null;
    }
  }
}

How to write a unit test case form this?

like image 602
Ankit Raonka Avatar asked Nov 15 '17 11:11

Ankit Raonka


People also ask

How do you write a test case for reactive form?

Step 1: Get the login form from component. Step 2: Create a dummy login form default value object. Step 3: At-last, compare both the form group values with dummy object. Step 2: Get the username value from the component form builder.

How do I create a custom validator?

in order to implement a custom validation directive, we need to implement the Validator interface, which only has the validate method. the validate method is going to call the validation creation function, and pass the control reference (the password control in this case) to the validator.

How can you add the validator function into the reactive forms?

Validating input in reactive formslink. In a reactive form, the source of truth is the component class. Instead of adding validators through attributes in the template, you add validator functions directly to the form control model in the component class.


2 Answers

Here's an example inspired by Subashan's answer which outlines the basic procedure:

import { maxTextLength } from '...';

describe('maxTextLength', () => {
  const maxTextLengthValidator = maxTextLength(10);
  const control = new FormControl('input');

  it('should return null if input string length is less than max', () => {
    control.setValue('12345');
    expect(maxLengthValidator(control)).toBeNull();
  });

  it('should return correct object if input string length is more than max', () => {
    control.setValue('12345678901');
    expect(maxLengthValidator(control)).toEqual({ maxTextLength: true });
  });
});

I haven't tested it but it's similar to something I've written and it shows the basic approach.

I would recommend changing validator parameter type to number:

export function maxTextLength(length: number) {
like image 174
camden_kid Avatar answered Sep 19 '22 04:09

camden_kid


You can create a from group in your test with one formControl (in this case some input).

Then leverage the setValue function of formControl to set a value that will pass the unit test.

Then you can pass this form control to the validator function and assert that it returns null (should return null if there's no error).

And another test for which there's an error.

like image 44
Subashan Maheswaramoorthy Avatar answered Sep 18 '22 04:09

Subashan Maheswaramoorthy