Franck
Franck

Reputation: 620

Jest / Vue test utils - Method coming from subcomponent scoped slot - [Vue warn]: Invalid handler for event "click": got undefined

I'm trying to test one of my component which calls a subcomponent (ie. b-modal).

My tested component uses scoped slots from b-modal to grab the close() method from it and attach it to another event listener. Have a look :

// My custom parent component
<template>
    <b-modal>
        <template #modal-header="{close}">
            <h2 class="card-header-title">
                Coordonnées
            </h2>
            <button class="close close-profile text-dark" @click="close">
                <i class="far fa-times" />
            </button>
        </template>
    </b-modal>
</template>

In my test, I mount my component like this :

return shallowMount(MyCustomParentComponent, {
    ...options,
    localVue,
    store,
    stubs: [
        "b-modal"
    ],
});

My test passes but Jest is throwing console.error warnings :

[Vue warn]: Invalid handler for event "click": got undefined
      
      found in
      
      ---> <Anonymous>
             <Root>
      

I guess my b-modal subcomponent is not fully mounted (stub, shallowMount) and the close() method is not injected.

What can I do ? Should I mock the close() method ? Silent the warnings ? Something else ?

Thanks for your help !

Upvotes: 2

Views: 1180

Answers (1)

tony19
tony19

Reputation: 138326

You could customize the stub of b-modal, rendering a modal-header slot with a mocked close():

it('should call close() on button click', async () => {
  const close = jest.fn()
  const ok = jest.fn()
  const cancel = jest.fn()
  const wrapper = shallowMount(MyModal, {
    stubs: {
      BModal: {
        render(h) {
          return h('div', [
                            this.$scopedSlots['modal-header']?.({close}),
                            this.$scopedSlots['default']?.({ok, cancel})
                          ]
                  )
        }
      }
    }
  });
  await wrapper.find('button.close').trigger('click')
  expect(close).toHaveBeenCalled()
})

Upvotes: 2

Related Questions