Unable to invoke @HostListener method with KeyDown event in the Unit Test case

Viewed 265

I have created a custom Directive using @Directive in which I am using @HostListener and fire a Keydown event, now the code works fine. Now, when writing the test case I need to invoke the @HostListener method from the unit test case. Also I can see that in the code coverage the code is not covered. Following is the code:

Specify-char-input-directive.ts

import { Directive, HostListener, Input } from '@angular/core';

@Directive({

  selector: '[tfbSpecifyCharInput]'
});

export class SpecifyCharInputDirective {
 
@Input() tfbSpecifyCharInput: string;

    key: any;

    ctrlKey: any;

    @HostListener('keydown', ['$event']) onKeydown(event: KeyboardEvent): any {

      this.key = event.code;

      this.ctrlKey = (['KeyV', 'KeyC', 'KeyX', 'KeyA'].indexOf(event.code) !== -1 && (event.ctrlKey || event.metaKey));

      const matchesNumber = /^[0-9]$/i.test(event.key);
      const matchesSpclChar = /[^a-zA-Z]$/i.test(event.key);
      const matchesAlpha = /^[A-ZÀ-ÿ-a-z`~/!@#%^&*-+=<>?,._#'${}|":;()]$/i.test(event.key) && !this.ctrlKey;

      if (this.tfbSpecifyCharInput === 'alpha' && matchesNumber) {
        event.preventDefault();
      }
      if (this.tfbSpecifyCharInput === 'alpha' && matchesSpclChar) {
        event.preventDefault();
      }
      if (this.tfbSpecifyCharInput === 'numeric' && matchesAlpha) {
        event.preventDefault();
      }
    }
}

Specify-char-input-directive.spec.ts

import { TestBed, ComponentFixture } from '@angular/core/testing';
import { Component, DebugElement, HostListener } from '@angular/core';
import { By } from '@angular/platform-browser';

import { SpecifyCharInputDirective } from './specify-char-input.directive';
@Component({
  template: `<p [tfbSpecifyCharInput]="'alpha'"></p>`
})
class TestComponent {
  // allows us to listen to keydown event
  key: any;
  @HostListener('keydown', ['$event']) onKeydown(event: KeyboardEvent): any {
     this.key = event.code;
  }
}

describe('tfbSpecifyCharInputDirective', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;
  let inputEl: HTMLElement;

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

    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    inputEl = fixture.nativeElement.querySelector('p');
  });

  it('should initialize directive with numeric only', () => {
    expect(component).toBeDefined();
  });

  it('should fire window keydown event', () => {
    const event: Event = new KeyboardEvent('keydown', {
      code: 'Enter'
    });
    inputEl.dispatchEvent(event);
    spyOn(event, 'preventDefault');
    fixture.detectChanges();
    expect(component.onKeydown).toBeTruthy();
  });

});

Below you can also see the code coverage report: enter image description here

Here I need to cover the code and get the proper test case executed required for this method. Thanks.

0 Answers
Related