Angular How to test @HostListener

Sam

I have the following directive. When applied to an input element, it checks for characters and calls preventDefault when the character is forbidden:

@Directive({
 selector: '[cdtPreventInput]'
})
  export class PreventInputDirective implements OnInit {

  // the list of characters that are to be prevented
  @Input() cdtPreventInput: String;

  constructor() { }

  ngOnInit() {
    if (!this.cdtPreventInput) {
      throw new Error('cdtPreventInput cannot be used without providing a 
          list of characters.');
    }
  }

 @HostListener('keypress', ['$event']) onKeyPress(event) {
   if (_.includes(this.cdtPreventInput.split(','), event.key)) {
    event.preventDefault();
  }
}

Works fine, but I can't figure out how to test it. I have the following so far:

describe('PreventInputDirective', () => {
  let fixture;
  let input: DebugElement;

  beforeEach(() => {
    fixture = TestBed.configureTestingModule({
      declarations: [PreventInputDirective, TestComponent]
    }).createComponent(TestComponent);

    input = fixture.debugElement.query(By.directive(PreventInputDirective));
  });

  it('should create an instance', () => {
    const directive = new PreventInputDirective();
    expect(directive).toBeTruthy();
  });

 it('should prevent default keypress event', () => {
    const event = new KeyboardEvent('keypress', {
      'key': '.'
    });
     input.nativeElement.dispatchEvent(event);

     expect(input.nativeElement.value).toEqual('');
  });

  @Component({
    template: `<input cdtPreventInput="." />`
  })
  class TestComponent { }
});

It's not working though. The keypress event is not triggered. Any idea how to test this directive ?

Sam

I found a solution. Instead of checking for value (which never changes), I just check the defaultPrevented property on the event.

I was also missing two things :

  • fixture.detectChanges(); in the beforeEach

  • event should be cancelable

Here's the full test :

 describe('PreventInputDirective', () => {
  let fixture;
  let input: DebugElement;

  beforeEach(() => {
    fixture = TestBed.configureTestingModule({
      declarations: [PreventInputDirective, TestComponent]
    }).createComponent(TestComponent);

    input = fixture.debugElement.query(By.directive(PreventInputDirective));
    fixture.detectChanges();
  });

  it('should create an instance', () => {
    const directive = new PreventInputDirective();
    expect(directive).toBeTruthy();
  });

  it('should prevent keypress event', () => {
    const event = new KeyboardEvent('keypress', {
      'key': '.',
      cancelable: true
    });

    input.nativeElement.dispatchEvent(event);
    expect(event.defaultPrevented).toBeTruthy();
  });

  it('should not prevent keypress event', () => {
    const event = new KeyboardEvent('keypress', {
      'key': '5',
      cancelable: true
    });

    input.nativeElement.dispatchEvent(event);
    expect(event.defaultPrevented).toBeFalsy();
  });

  @Component({
    template: `<input cdtPreventInput="." />`
  })
  class TestComponent { }
});

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Angular: How I can test @HostListener in jasmine?

How to test HostListener window scroll on Angular?

Unit Test Angular for HostListener

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

How to avoid hardcoded @HostListener events in Angular 11?

Angular unit test case for @HostListener escape key event

Is it possible to use HostListener in a Service? Or how to use DOM events in an Angular service?

How to Find the Browser Tab is Focused or Not using HostListener in Angular 2+

How To Prevent Window Close Event Using HostListener In Angular 2+

How to use @HostListener when location.hash changed? (angular 2)

How to use HostListener

Angular - Is there list of HostListener-Events?

Angular 4 load event with @HostListener

Component specific HostListener in angular 2

HostListener on outside click Angular 6

Angular activate @HostListener in ngAfterViewInit or ngOnInit

how to get target element id from @HostListener, angular2 directive

Angular2, HostListener, how can I target an element? can I target based on class?

How can I pass non-string values to a HostListener function in Angular?

How can I capture any scroll event from an element on the page using HostListener (Angular 7)?

Unable to invoke @HostListener method in the Unit Test case

How to preventDefault() in HostListener Input action

How to make HostListener for scroll work?

How to get a keyCode for *focus* HostListener

Angular 2 - Binding and Unbinding HostListener Events

angular directive multiple selectors and @HostListener, @HostBinding

Angular 11 - @HostListener "window:beforeunload" is triggered twice

Angular 2 HostListener keypress detect escape key?

Disable HostListener beforeunload on Angular 2+