[SalesForce] Simulating a lightning button menu onchange event through jest

I've been trying to write some unit tests for a lightning-button-menu component. With the lwc file as:

<lightning-button-menu onselect={onSelectMethod} class="edit-record-wrapper">
    <lightning-menu-item value="details" label="edit" class="edit-record-button"></lightning-menu-item>
</lightning-button-menu>

however a jest file containing:

const buttonEl = element.shadowRoot.querySelector('.edit-record-button');
buttonEl.click();

does not trigger the onSelectMethod. It appears this is an issue when testing react js (see https://stackoverflow.com/questions/48180499/testing-onchange-function-in-jest), and the solution is to use a

wrapper.find('.event-menu-wrapper').simulate('change',{target:{'details}})

where wrapper is some form of reference to their component(?) that is different to what we have available when using jest with LWC.

Does anyone have any pointers or advice on how to simulate this onchange event?

Many thanks

Best Answer

You can dispatch an event directly on the element to force event handlers to be called. Using your example, to force the onSelectMethod callback to be called you could do the following in your test:

const lightningButtonMenu = element.shadowRoot.querySelector('lightning-button-menu');
lightningButtonMenu.dispatchEvent(new CustomEvent('select'));

And then if need to pass some payload along with the event you can pass data in to the second parameter of the CustomEvent constructor. lwc-recipes has some examples of this:

const contactListItemEls = element.shadowRoot.querySelector(
    'c-contact-list-item-bubbling'
);
contactListItemEls.dispatchEvent(
    new CustomEvent('contactselect', {
        detail: { ...detail payload here... },
        bubbles: true
    })
);