I am writing a modal component in vue 3:
<code>// MyModal.vue
<script setup>
const emit = defineEmits(['close'])
const modalDialog = ref(null)
const close = () => {
emit('close')
modalDialog.value.close()
}
defineExpose({
close
})
</script>
<template>
<dialog ref="modalDialog">
<h1>My Modal</h1>
<slot />
</dialog>
</template>
</code>
<code>// MyModal.vue
<script setup>
const emit = defineEmits(['close'])
const modalDialog = ref(null)
const close = () => {
emit('close')
modalDialog.value.close()
}
defineExpose({
close
})
</script>
<template>
<dialog ref="modalDialog">
<h1>My Modal</h1>
<slot />
</dialog>
</template>
</code>
// MyModal.vue
<script setup>
const emit = defineEmits(['close'])
const modalDialog = ref(null)
const close = () => {
emit('close')
modalDialog.value.close()
}
defineExpose({
close
})
</script>
<template>
<dialog ref="modalDialog">
<h1>My Modal</h1>
<slot />
</dialog>
</template>
I am writing a test to cover the modal component’s close()
method. For this, I am trying to mock the ref, but I am getting error modalDialog.value.close is not a function
when executing the test. The component works well in the browser, but not in vitest.
<code>// MyModal.spec.js
const closeMock = vi.fn()
describe('MyModal', () => {
test('close()', () => {
const wrapper = mount(MyModal)
wrapper.vm.modalDialog.value = {
close: closeMock
}
wrapper.vm.close()
expect(closeMock).toHaveBeenCalled()
})
})
</code>
<code>// MyModal.spec.js
const closeMock = vi.fn()
describe('MyModal', () => {
test('close()', () => {
const wrapper = mount(MyModal)
wrapper.vm.modalDialog.value = {
close: closeMock
}
wrapper.vm.close()
expect(closeMock).toHaveBeenCalled()
})
})
</code>
// MyModal.spec.js
const closeMock = vi.fn()
describe('MyModal', () => {
test('close()', () => {
const wrapper = mount(MyModal)
wrapper.vm.modalDialog.value = {
close: closeMock
}
wrapper.vm.close()
expect(closeMock).toHaveBeenCalled()
})
})
Here is an example of how I use the modal component:
<code><script setup>
import MyModal from './MyModal.vue'
const myModal = ref()
const openMyModal = () => {
myModal.value.open()
}
const closeMyModal = () => {
myModal.value.close()
}
</script>
<template>
<my-modal ref="myModal" >
<template #default>
<MyComponent @close:modal="closeMyModal" />
</template>
</my-modal>
</template>
</code>
<code><script setup>
import MyModal from './MyModal.vue'
const myModal = ref()
const openMyModal = () => {
myModal.value.open()
}
const closeMyModal = () => {
myModal.value.close()
}
</script>
<template>
<my-modal ref="myModal" >
<template #default>
<MyComponent @close:modal="closeMyModal" />
</template>
</my-modal>
</template>
</code>
<script setup>
import MyModal from './MyModal.vue'
const myModal = ref()
const openMyModal = () => {
myModal.value.open()
}
const closeMyModal = () => {
myModal.value.close()
}
</script>
<template>
<my-modal ref="myModal" >
<template #default>
<MyComponent @close:modal="closeMyModal" />
</template>
</my-modal>
</template>