1

Vue-test-utils is unable to detect method call when using @click attribute on child component, but is able to detect it when using the @click attribute on a native HTML-element, e.g. a button. Let me demonstrate:

This works:

// Test.vue
<template>
    <form @submit.prevent>
        <button name="button" type="button" @click="click">Test</button>
    </form>
</template>

<script>
import { defineComponent } from 'vue'

export default defineComponent({
    name: 'Test',
    setup() {
        const click = () => {
            console.log('Click')
        }

        return { click }
    }
})
</script>

// Test.spec.js
import { mount } from '@vue/test-utils'
import Test from './src/components/Test.vue'

describe('Test.vue', () => {
    const wrapper = mount(Test)

    if ('detects that method was called', () => {
        const spy = spyOn(wrapper.vm, 'click')
        wrapper.find('button').trigger('click')
        expect(wrapper.vm.click).toHaveBeenCalled() // SUCCESS. Called once
    })
})

This does NOT work:

// Test.vue
<template>
    <form @submit.prevent>
        <ButtonItem @click="click" />
    </form>
</template>

<script>
import { defineComponent } from 'vue'
import ButtonItem from './src/components/ButtonItem.vue'

export default defineComponent({
    name: 'Test',
    components: { ButtonItem },
    setup() {
        const click = () => {
            console.log('Click')
        }

        return { click }
    }
})
</script>

// ButtonItem.vue
<template>
    <button type="button">Click</button>
</template>

<script>
import { defineComponent } from 'vue'

export default defineComponent({
    name: 'ButtonItem',
})
</script>

// Test.spec.js
import { mount } from '@vue/test-utils'
import Test from './src/components/Test.vue'
import ButtonItem from './src/components/ButtonItem.vue'

describe('Test.vue', () => {
    const wrapper = mount(Test)

    if ('detects that method was called', () => {
        const spy = spyOn(wrapper.vm, 'click')
        wrapper.findComponent(ButtonItem).trigger('click')
        expect(wrapper.vm.click).toHaveBeenCalled() // FAIL. Called 0 times
    })
})

This issue stumbles me. I am not sure what I do wrong. I would be grateful if someone could describe the fault and show me the solution. Thanks!

1
  • I have this exact same issue. Have you been able to fix it yet? Commented Apr 11, 2022 at 9:02

1 Answer 1

1

I haven't run your code to test it yet, but why won't you use a more straightforward solution?

Look out for when the component emits click.

describe('Test.vue', () => {
    const wrapper = mount(Test)

    it('when clicked on ButtonItem it should be called one time', () => {
        const button = wrapper.findComponent(ButtonItem)
        button.trigger('click')
        expect(wrapper.emitted().click).toBeTruthy()
        expect(wrapper.emitted().click.length).toBe(1)
    })
})
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. That's a nice alternative solution. However, I am still interesting why my code does not work :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.