Search code examples
angularkarma-jasmineangular-directivekeyboard-eventsangular-unit-test

Unit test Keypress event directive in angular


I have a directive that prevents users from entering the alphabets. for unit testing I planned to execute that I will trigger a keypress event and if its number it will be there in the text box if not it should not. when I run the test, the event and char code is matching and the function returning true but I am not able to see the value in the text box.

Directive

  @HostListener('keypress', ['$event']) onKeyPress(event: any) {
    let enteredChar: number;
    enteredChar = parseInt(event.charCode, 10);
    return enteredChar >= 47 && enteredChar <= 57;
  }

Unit test

@Component({
  template: `
    <input PreventSpecialCharacters id="testComp" type="text" />
  `
})
class TestSpecialCharComponent {
  constructor(private el: ElementRef) {}
}

fdescribe('PreventSpecialCharactersDirective', () => {
  let fixture: ComponentFixture<TestSpecialCharComponent>;
  let inputEl: HTMLInputElement;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        TestSpecialCharComponent,
        PreventSpecialCharactersDirective
      ]
    });
    fixture = TestBed.createComponent(TestSpecialCharComponent);
    inputEl = fixture.nativeElement.querySelector('#testComp');
  });

  fit('should allow the input', () => {
    fixture.detectChanges();
    inputEl.dispatchEvent(makeKeyPressEvent('Digit1', 49, 49));
    expect(inputEl.value).toEqual('1');
  });

Solution

  • I have to create a custom click event and directly passing that to the function that needs to be tested.

      function makeKeyPressEvent(
        keyName: string,
        keyCode: number,
        charCode: number
      ) {
        const event = new KeyboardEvent('keypress');
        Object.defineProperties(event, {
          charCode: { value: charCode },
          keyCode: { value: keyCode },
          keyIdentifier: { value: keyName },
          which: { value: keyCode }
        });
        return event;
      }
    

    and the test was like below

       const directive = new PreventSpecialCharactersDirective();
        const result = directive.onKeyPress(makeKeyPressEvent('Digit1', 49, 49));
        expect(result).toBeTruthy();