Anand Bhushan
Anand Bhushan

Reputation: 783

What is the difference between dispatchEvent() and triggerEventHandler() in angular unit testing using karma?

I am writing unit test for a directive(called on input event), which is modifying an input value on a formControl. I've created a test component in my spec file for the same. I noticed a difference between triggerEventHandler() and dispatchEvent(), while dispatchEvent() was triggering the event correctly and directive was triggered, in the case of triggerEventHandler() event wasn't triggered. Can anyone let me know, what's the difference between them, apart from that dispatchEvent() is called on nativeElement.

// directive
export class AlphaNumericCheckDirective {

  constructor(private ctrl: NgControl) {
  }
  @HostListener('input')
  onInputChange() {
    const pattern = /[^0-9]/g;
    const elVal = (this.ctrl.control as AbstractControl).value;
    if (pattern.test(elVal)) {
      const newVal = elVal.replace(pattern, '');
      (this.ctrl.control as AbstractControl).setValue(newVal);
    }
  }
}

// relevant code of test
it('should allow only numerics', () => {
   const fixture = TestBed.createComponent(TestComponent);
   const inputEl = fixture.debugElement.query(By.css('input'));
   (fixture.componentInstance.testGroup.get('testControl') as 
   AbstractControl).patchValue('12a');
   inputEl.triggerEventHandler('input', null); // not triggering the directive
   inputEl.nativeElement.dispatchEvent(new Event('input')); // triggering the directive
});

Upvotes: 10

Views: 12254

Answers (2)

Pritam Bohra
Pritam Bohra

Reputation: 4339

triggerEventHandler belongs to Angular. The triggerEventHandler will invoke the event handler only if it was declared on the native element by using Angular event bindings, the @HostListener() or @Output decorators.

dispatchEvvent comes in handy when we define events via JS native APIs, for eg. RxJS fromEvent observable, etc.

We can even use dispatchEvent to simulate Angular Material component's event while testing, as triggerEventHandler would not work there since Angular doesn’t know about those events.

Here's a very interesting article that will help you understand the difference neatly https://netbasal.com/simulating-events-in-angular-unit-tests-5482618cd6c6

Upvotes: 7

Tim
Tim

Reputation: 93

I noticed same issue as well. What I found is triggerEventHandler() works in the button testing scenario but not the input case while dispatchevent works in the input scenario which is your case.

Upvotes: 0

Related Questions