Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest testing of dispatchEvent with CustomEvent

I am getting false positives trying to test that a certain CustomEvent was dispatched in a class. I am using jest.spyOn to test what specific CustomEvent was passed through the dispatchEvent call. Here is the function that dispatches a custom event:

someFunction() {
    this.dispatchEvent(
        new CustomEvent('myEvent', {
            bubbles: true,
            composed: true,
            detail: { someProperty: this.localProperty },
        })
    );
}

And the test attempts to validate the expected event this way:

let container;

beforeEach(() => {
    container = new SomeClass();
});


it('dispatches correct CustomEvent when someFunction is called', () => {
    const dispatchEventSpy = jest.spyOn(container, 'dispatchEvent');
    container.localProperty = '123';
    const customEvent = new CustomEvent('myEvent', {
        bubbles: true,
        composed: true,
        detail: { someProperty: 'wrong value' },
    });
    container.someFunction();
    // TODO: I expect the below to fail because the format passed in the custom event does not match the format in the container.
    expect(dispatchEventSpy).toHaveBeenCalledWith(customEvent);
    // If I use toBe instead and check the argument passed to dispatchEvent this way it fails even when they are the same. So I either get a false positive or a false negative.
    expect(dispatchEventSpy.mock.calls[0][0]).toBe(customEvent);
});
like image 920
davidethell Avatar asked Nov 11 '20 10:11

davidethell


2 Answers

If you log this objects inside jest unit test you will see the result is very similar:

console.log(new CustomEvent("myEvent", {
   bubbles: true,
   composed: true,
   detail: { someProperty: "123" },
}));
console.log(new CustomEvent("myEvent", {
  bubbles: true,
  composed: true,
  detail: { someProperty: "error" },
}));

In my case the result for both was: { isTrusted: [Getter] }

And that is why this won't fail:

expect(dispatchEventSpy).toHaveBeenCalledWith(customEvent);

You can access the expected object for a better assertion using dispatchEventSpy.mock.calls[0][0]:

  expect(dispatchEventSpy.mock.calls[0][0].detail).toEqual({
    someProperty: "123",
  });
  expect(dispatchEventSpy.mock.calls[0][0].bubbles).toEqual(true);
  expect(dispatchEventSpy.mock.calls[0][0].composed).toEqual(true);
like image 147
lissettdm Avatar answered Sep 25 '22 21:09

lissettdm


Custom event can also be tested like below

if (!window.CustomEvent) {
  CustomEvent = function(name, params){ return params;};
}
document.dispatchEvent = jest.fn();
expect(document.dispatchEvent.mock.calls.length).toEqual(0);
someFunction() // this is a function which is having customEvent and dispatching that event
expect(document.dispatchEvent.mock.calls.length).toEqual(1);
like image 38
Ashwani Panwar Avatar answered Sep 21 '22 21:09

Ashwani Panwar