Angular2 how to unit test a custom validator directive?

Robin Dijkhof

I wrote a very simple custom validor for an input field:

import { Directive } from '@angular/core';
import { AbstractControl, NG_VALIDATORS } from '@angular/forms';

function numberValidator(c: AbstractControl) {
    if (!c.value) return null;
    return new RegExp('^[1-9][0-9]{6,9}$').test(c.value) ? null : {
        validateNumber: {
            valid: false
        }
    }
}

@Directive({
    selector: '[number-validator]',
    providers: [
        { provide: NG_VALIDATORS, multi: true, useValue: numberValidator }
    ]
})
export class NumberValidator {

}

I would like to unittest this validator. I read Test an attribute directive on the Angular2 page, but there is no css or html that changes. How can I unittest this validator?

Paul Samsotha

If you want to do it the easy way (which I would do, since all the logic is in the validator function), is just to test the validator function. Just pass a control to it

expect(numberValidator(new FormControl('123456'))).toEqual({
  'validateNumber': { 'valid': false }
});
expect(numberValidator(new FormControl('123456789'))).toEqual(null);

If you really want to test it when "being used", then it gets a little tedious. These are usually the steps I take

  1. Create dummy component to use the directive
  2. Set up the test bed configuration
  3. Create the component to test.
  4. Get the native input element and dispatch an invalid input event to it
  5. Get the injector that holds the NgForm
  6. Check the form for failure
  7. Put a valid input and check that it passes.

It's a lot compared to just testing the validator method. But here it is anyway ;-) Enjoy!

import { Component, Directive } from '@angular/core';
import { TestBed, async } from '@angular/core/testing';
import { dispatchEvent } from '@angular/platform-browser/testing/browser_util';
import { By } from '@angular/platform-browser';
import { FormsModule, NG_VALIDATORS, AbstractControl,
         NgForm, FormControl } from '@angular/forms';

function numberValidator(c: AbstractControl) {
  if (!c.value) return null;
  return new RegExp('^[1-9][0-9]{6,9}$').test(c.value) ? null : {
    validateNumber: {
      valid: false
    }
  };
}

@Directive({
  selector: '[number-validator]',
  providers: [
    { provide: NG_VALIDATORS, multi: true, useValue: numberValidator }
  ]
})
export class NumberValidator {
}

@Component({
  template: `
    <form>
      <input name="number" type="text" ngModel number-validator />
    </form>
  `
})
class TestComponent {
}

describe('component: TestComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ FormsModule ],
      declarations: [TestComponent, NumberValidator]
    });
  });

  it('should validate (easy)', () => {
    expect(numberValidator(new FormControl('123'))).toEqual({
      'validateNumber': { 'valid': false }
    });
    expect(numberValidator(new FormControl('123456789'))).toEqual(null);
  });

  it('should validate (tedious)', async(() => {
    let fixture = TestBed.createComponent(TestComponent);
    let comp = fixture.componentInstance;
    let debug = fixture.debugElement;
    let input = debug.query(By.css('[name=number]'));

    fixture.detectChanges();
    fixture.whenStable().then(() => {
      input.nativeElement.value = '123';
      dispatchEvent(input.nativeElement, 'input');
      fixture.detectChanges();

      let form: NgForm = debug.children[0].injector.get(NgForm);
      let control = form.control.get('number');

      // just to show a few different ways we can check validity
      expect(control.hasError('validateNumber')).toBe(true);
      expect(control.valid).toBe(false);
      expect(form.control.valid).toEqual(false);
      expect(form.control.hasError('validateNumber', ['number'])).toEqual(true);

      input.nativeElement.value = '123456789';
      dispatchEvent(input.nativeElement, 'input');
      fixture.detectChanges();

      expect(form.control.valid).toEqual(true);
    });
  }));
});

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Javascript

How to Unit Test a Directive In Angular 2?

From Javascript

How to Unit Test Isolated Scope Directive in AngularJS

From

How to implement Custom Async Validator in Angular2/4/5

From

How to unit test a FormControl in Angular2

From

How to change value of a select box in angular2 unit test?

From Dev

Unit test angular directive that uses ngModel

From Dev

Unit test angular directive updating the ngModel

From Dev

Angular Unit Test - Click in directive not triggering

From Dev

Unit test Angular directive that accesses external element

From Dev

Angular2 how to pass a parameter into a custom form control validator?

From Dev

Mock custom service in angular2 during unit test

From Dev

How to unit test Angular routeChangeSuccess in directive link function?

From Dev

Angular2: How to modify content of the element with custom directive?

From Dev

Angular2 jasmine unit test component with third party directive

From Dev

Writing Unit test for Angular6 directive

From Dev

How to write unit test for structural directive prefixed with an asterisk * in Angular

From Dev

Unit test angular right-click directive

From Dev

How do I trigger a click event in a unit test for an Angular directive

From Dev

How to unit test spy on $emit in a directive?

From Dev

Test directive used as general custom validator

From Dev

Unit test $formatters in Angular directive

From Dev

How to make a custom validator in Angular2

From Dev

Unit Test Custom Validator in Spring Validation

From Dev

Custom validator attribute works in unit test but not web api controller?

From Dev

Validator unit test fails because of custom constraint validator

From Dev

How to unit test an Hostlistener onChange event in a directive in angular?

From Dev

Angular Unit Test for Custom Validator FormGroup

From Dev

Angular custom directive for fromdate todate validator not loading

From Dev

Angular unit test custom validator Cannot read properties of undefined (reading 'dobLengthValidator')

Related Related

  1. 1

    How to Unit Test a Directive In Angular 2?

  2. 2

    How to Unit Test Isolated Scope Directive in AngularJS

  3. 3

    How to implement Custom Async Validator in Angular2/4/5

  4. 4

    How to unit test a FormControl in Angular2

  5. 5

    How to change value of a select box in angular2 unit test?

  6. 6

    Unit test angular directive that uses ngModel

  7. 7

    Unit test angular directive updating the ngModel

  8. 8

    Angular Unit Test - Click in directive not triggering

  9. 9

    Unit test Angular directive that accesses external element

  10. 10

    Angular2 how to pass a parameter into a custom form control validator?

  11. 11

    Mock custom service in angular2 during unit test

  12. 12

    How to unit test Angular routeChangeSuccess in directive link function?

  13. 13

    Angular2: How to modify content of the element with custom directive?

  14. 14

    Angular2 jasmine unit test component with third party directive

  15. 15

    Writing Unit test for Angular6 directive

  16. 16

    How to write unit test for structural directive prefixed with an asterisk * in Angular

  17. 17

    Unit test angular right-click directive

  18. 18

    How do I trigger a click event in a unit test for an Angular directive

  19. 19

    How to unit test spy on $emit in a directive?

  20. 20

    Test directive used as general custom validator

  21. 21

    Unit test $formatters in Angular directive

  22. 22

    How to make a custom validator in Angular2

  23. 23

    Unit Test Custom Validator in Spring Validation

  24. 24

    Custom validator attribute works in unit test but not web api controller?

  25. 25

    Validator unit test fails because of custom constraint validator

  26. 26

    How to unit test an Hostlistener onChange event in a directive in angular?

  27. 27

    Angular Unit Test for Custom Validator FormGroup

  28. 28

    Angular custom directive for fromdate todate validator not loading

  29. 29

    Angular unit test custom validator Cannot read properties of undefined (reading 'dobLengthValidator')

HotTag

Archive