vue.jsvitestvue-test-utils

Vue Testing: Triggering Checkbox not working


I'm trying to test if a checkbox has been checked with Vue test utils and Vitest, but the test always fails and I don't understand why.

Component.vue:

<template>
    <input type="checkbox" @change="check($event.target.checked)">
  </template>
  
  <script>
  export default {
    data() {
        return {
            selected: false
        }
    },
    methods: {
        check(checked) {
            console.log(checked)
            this.selected = checked
        }
    }
  }
  </script>

component.spec.js:

import { mount } from '@vue/test-utils'
import Component from '.././src/components/Component.vue'
import { expect, test } from 'vitest'
import { nextTick } from 'vue'

test('props', async () => {
    const wrapper = mount(Component)
    await wrapper.find("input[type='checkbox']").trigger("change")
    await nextTick()
    expect(wrapper.vm.selected).toBe(true)
})

The test output is always:

 FAIL  test/component.spec.js > checkbox
AssertionError: expected false to be true // Object.is equality

- Expected
+ Received

- true
+ false

 ❯ test/component.spec.js:10:33
      8|     await wrapper.find("input[type='checkbox']").trigger("change")
      9|     await nextTick()
     10|     expect(wrapper.vm.selected).toBe(true)
       |                                 ^
     11| })

I have already asked AI, and also looked here on StackOverflow. Although there were a lot of similar problems, none of the suggestions worked.

Can someone please explain to me what the problem is and how to resolve it? Thank you in advance.


Solution

  • Thanks to Estus Flask (see comments under the question) I found the solution. I changed the @change in the Vue component to @click.

    The modified Component.vue:

    <template>
        <input type="checkbox" @click="this.selected = $event.target.checked">
      </template>
      
      <script>
      export default {
        data() {
            return {
                selected: false
            }
        },
      }
      </script>
    

    The modified component.spec.js:

    import { mount } from '@vue/test-utils'
    import Component from '.././src/components/Component.vue'
    import { expect, test } from 'vitest'
    
    test('checkbox', async () => {
        const wrapper = mount(Component)
        const checkbox = wrapper.find("input[type='checkbox']")
        await checkbox.trigger("click")
        expect(wrapper.vm.selected).toBe(true)
    })