1

Please help out with testing custom validator. Two weeks trying to resolve this issue nothing happens.

in html

<div>
<input type="text" class="value-input"  [(ngModel)]="element.value" name = "RegisterValue" #ValueReg = "ngModel"  [viewRegister] = 'viewChoiceDispleyReg' [viewType] = 'displeyView' valueName>
</div>

directive

import { AbstractControl, ValidatorFn, FormControl } from '@angular/forms';
import { Directive, ElementRef, Input } from '@angular/core';
import { NG_VALIDATORS, Validator } from '@angular/forms';

@Directive({
    selector: '[valueName]',
    providers: [
        { provide: NG_VALIDATORS, useExisting: valueValidator, multi: true }
      ]
  })
  export class valueValidator implements Validator{

  validator: ValidatorFn;
  @Input('viewType') viewType;
  @Input('viewRegister') viewRegister;

  constructor(private elementRef: ElementRef) {
    this.validator = this.validateValueFactory();
  }

  validate(c: FormControl) {
    return this.validator(c);
  }

  // validation function
  validateValueFactory() : ValidatorFn {
    return (c: AbstractControl) => {
      console.log("validate: " + c.value + ", view type: " + this.viewType);
      let isValid = c.value === '0';

      if(isValid) {
          return null;
      } else {
          return {
              valueName: {
                  valid: false
              }
          };
        }
    }
  } 
}

I've studied a lot of material on stackoverflow on other sites. The main problem is that I don't know how to create a component for testing the validator. In this test the component is to add the required validator for the properties(@viewType, @viewRegister). How write unit tests for this validator?

2 Answers 2

1

Here is a useful guide to testing directives.

in summary:

  1. create a dummy component as part of your test
  2. provide the HTML for that dummy component
  3. Make sure to declare the dummy component and the directive in the testbed module setup
  4. write your asserstions.

Something along the lines of...

import {valueValidator } from '[pathToValidator]';
@Component({
  template: `
    <div>
        <input type="text" class="value-input"  [(ngModel)]="element.value" name = "RegisterValue" #ValueReg = "ngModel"  [viewRegister] = 'viewChoiceDispleyReg' [viewType] = 'displeyView' valueName>
    </div>
    `
})
class DummyComponent {}

describe('valueValidator ', () => {

    let component: DummyComponent;
    let fixture: ComponentFixture<DummyComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        DummyComponent,
        valueValidator
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(DummyComponent);
    component = fixture.componentInstance;
  });


  it('should create an instance', () => {
    expect(component).toBeTruthy();
    // insert additional assertions here.
  });
});
Sign up to request clarification or add additional context in comments.

Comments

0

It so happened that a lot of the time I spent on what to write one test. The comment I leave in order to facilitate the finding of solutions. Let me remind you that custom validator gives an error if the number entered is different from 0. Need do: 1) create test component

@Component({
  template: `
    <form>
    <input type="text" class="value-input" [(ngModel)]="element" name="register" #ValueReg = "ngModel"  
    [viewRegister] = 'viewChoiceDispleyReg' [viewType] = 'displeyView' valueName>
    </form>
  `
})class TestComponent {
  public element: string = '1';
  public viewRegister: string = Constant.DISPLEY_VIEW[0];
  public viewType: string = Constant.DISPLEY_VIEW[1];
}

2) Init test

describe('Custom validation valueValidator', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;
  beforeEach(() => {
      TestBed.configureTestingModule({
        declarations: [
          TestComponent,
          valueValidator,
        ],
        imports: [
          BrowserModule,
          FormsModule
        ],
      }).compileComponents();

    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
  });
});

3) write test

it('set value 2 get error', () => {
    fixture.detectChanges();

    fixture.whenStable().then(() => {

      let comp = fixture.componentInstance;
      let debug = fixture.debugElement;
      let input = debug.query(By.css('[name=register]'));
      let inputElement = input.nativeElement;

      inputElement.value = '2';//set intresting value
      inputElement.dispatchEvent(new Event('input'));//load value to input 

      let form: NgForm = fixture.debugElement.children[0].injector.get(NgForm);
      let control = form.control.get('register');
      expect(control.valid).toBe(false);
    })
  });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.