Home > other >  Unit test for renderer listen method on custom event
Unit test for renderer listen method on custom event

Time:07-23

I have the below method that listens to a custom event and sets the focus of the element. I want to write a unit test for this method. I am trying to mock the focus element focus and using fakeAsync to provide a little delay and also mocking the renderer listener but the coverage is not getting through this method.

listenToModalCloseEvent() {
    this.modalListenerFn = this.renderer.listen(document, 'popupClosed', () => {
      if (this.focusElement) {
        setTimeout(() => {
          this.focusElement.focus();
        }, 0);
      }
    });
  }

here is what I have trid,

it('should call listenToModalCloseEvent', fakeAsync(() => {
    dummyElement.dispatchEvent(new Event('popupClosed', { bubbles: true }));
    service.focusElement = dummyElement;
    service.listenToModalCloseEvent();
    const spy = spyOnProperty(service, 'focusElement').and.returnValue({ focus: () => {}});
    spyOn((service as any).renderer, 'listen').and.callThrough();
    tick(100);
    expect(service.focusElement).toBeDefined();
    expect(spy).toHaveBeenCalled();
  }))

Don't where I am wrong

CodePudding user response:

The main issue is that you're dispatching popupClosed event before the subscription to that event. Also:

  • you can spy directly on focusElement.focus() method
  • you don't need to pass 100 to tick method if setTimeout is called with 0
  • I don't know how you defined dummyElement so I just created it manually.

Here's the final test:

it('should call listenToModalCloseEvent', fakeAsync(() => {
  const dummyElement = document.createElement('input')!;
  document.body.appendChild(dummyElement); // now it can propagate events to the document

  service.focusElement = dummyElement;
  service.listenToModalCloseEvent();
  const spy = spyOn(dummyElement, 'focus');
  dummyElement.dispatchEvent(new Event('popupClosed', { bubbles: true }));
  dummyElement.remove(); // remove input from the page
  tick(0);
  expect(service.focusElement).toBeDefined();
  expect(spy).toHaveBeenCalled();
}))

btw, expect(service.focusElement).toBeDefined(); looks weird because you explicitly assigned that property to class.

  • Related