vue-test-utils: Spying on a method does not work

Subject of the issue

When I trigger a click event on a component when spying a function, the function is called, but the spy does not work

Steps to reproduce

Here is my component:

<template>
	<button class="close-btn no-select" @click="close" @keydown.esc="close" />
</template>

<script>
	export default {
		name: 'CoreCloseButton',

		methods: {
			close() {
				this.$emit('close')
			},
		},
	}
</script>

Here is my test:

import { shallowMount } from "@vue/test-utils"

import CoreCloseButton from "./CoreCloseButton"

describe("CoreCloseButton.vue", () => {
	it('Should call close method when click on button', async () => {
		const wrapper = shallowMount(CoreCloseButton)

                let spyClose = jest.spyOn(wrapper.vm, 'close')

                await wrapper.trigger('click')

                expect(spyClose).toBeCalled()
	})
})

Expected behaviour

The spy should be called

Actual behaviour

The spy is not called

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (5 by maintainers)

Most upvoted comments

I had the same issue, where I tried to use .toHaveBeenCalled(), which returned in 0 calls for me. I found out, that when I call the method with parenthesis in the component itself, my spy actually works.

from @click="addEntry" to @click="addEntry()"

Hi! You might want to spy on the component definition, not on the vm instance:

  it('Should call close method when click on button', async () => {
    const spyClose = jest.spyOn(CoreCloseButton.methods, 'close') // Notice how this line changed

    const wrapper = shallowMount(CoreCloseButton)

    await wrapper.trigger('click')

    expect(spyClose).toBeCalled()
  })

Moreover, I’d suggest not testing the internals of the component (in this case, if a specific method is called), but rather the “effects” of calling that method – the emitted event:

  it('Should call close method when click on button', async () => {
    const wrapper = shallowMount(CoreCloseButton)

    await wrapper.trigger('click')

    expect(wrapper.emitted('close')).toHaveLength(1)
  })

hope it helps!

You may solve this problem if you spy on a method like this :

  it('Should call close method when click on button', async () => {
    const spyClose = jest.spyOn(CoreCloseButton.options.methods, 'close') // Notice how this line changed
    const wrapper = shallowMount(CoreCloseButton)
    await wrapper.trigger('click')
    expect(spyClose).toBeCalled()
  })

Your solution works for me @okakyo thank you!