Home > Mobile >  Unit test for fromEvent in service
Unit test for fromEvent in service

Time:08-20

I've a service that detects if a CTRL/CMD key is pressed. It is used in various components to check (among other things) if links should open in a new tab or not.

Service:

keyDownListenerCTRL = fromEvent<KeyboardEvent>(window, 'keydown').pipe(
tap((event: KeyboardEvent) => {
  if (
    event.metaKey ||
    event.ctrlKey ||
    event.key === 'Meta' ||
    event.key === 'Ctrl'
  ) {
    this.isControlButtonHeld = true;
  }
})
);

constructor() {
    this.keyDownListenerCTRL.subscribe();
}

I don't know how to test this. There is no HTML element that I could simulate a click on, so using a dispatchEvent (like suggested here) does not work.

CodePudding user response:

It should be the same thing as the answer you linked to, but on the window object.

const evt = new KeyboardEvent("keydown", {   
  key: 'Control',
  code: 'ControlLeft',
  ctrlKey: true
});
window.dispatchEvent(evt);

A few things...

  • You might be better off using renderer.listen to attach to the event. This way you don't have to reference an non-injected global object like window, and the technique above will still work.
  • If you can, consider using HostListener instead of fromEvent as now testing is a simple as calling a method.
// injecting document and using renderer.
constructor (private renderer: Renderer2) { 
  this.renderer.listen('window', 'keydown', event => { /* do stuff */ });
}

// Using HostListner to listen to control and escape
@HostListener('window:keydown.control')
@HostListener('window:keydown.escape')
onKeyDown(evt: KeyboardEvent) {
  this.isControlButtonHeld = true;
}
  • Related