directive with custom validator not firing in test when I set the value

Viewed 15

I've got a directive which has a custom validator function..

@Directive({
  selector: '[myDirective]',
  providers: [{
    provide: NG_VALIDATORS,
    useExisting: MyDirective,
    multi: true
  }]
})
export class MyDirective implements OnInit {
  ...
  validate(control: AbstractControl): ValidationErrors | null {
    console.log('validations running', control.value);
  }
}

...

In my test, I am using this directive like:

@Component({
  template: `
<form [formGroup]="formGroup">
    <input formControlName="test" myDirective />
</form>
`
})
class TestComponent implements OnInit {
  formGroup!: FormGroup;

  ngOnInit () {
    this.formGroup = new FormGroup({
      test: new FormControl('', { updateOn: 'blur' }),
    });
  }
}

describe('myDirective', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;
  let input: HTMLInputElement;

  beforeEach(() => {
    const testBed = getTestBed();
    testBed.configureTestingModule({
      imports: [
        ReactiveFormsModule,
      ],
      declarations: [
        MyDirective
        TestComponent,
      ]
    });
    testBed.compileComponents();
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    input = fixture.debugElement.query(By.css('input')).nativeElement;
  });

  it('has validation', () => {
    console.log('setting value');
    input.value = 'something-invalid';

    // trying really hard to get validations to trigger...
    const event = new MouseEvent('blur', {});
    input.dispatchEvent(event);
    fixture.detectChanges();

    // nope.. validation function not called..

    const formControl = component.formGroup.get('test');
    formControl.markAsDirty();
    formControl.markAsTouched();
    formControl.updateValueAndValidity();

    // ok finally the validator function is called-- but control.value is blank, even though I set the value of the input to 'somthing-invalid'...
  });

The output of my test is:

LOG: validations running, ''
Log: setting value
LOG: validations running, ''

It apparently runs initially after ngOnInit for my test component is called, and then a second time but for some reason it is not getting called. How can I get my validator to fire with the actual value set on the input?

0 Answers
Related