Testing user interactions helps make sure your app works as expected when people click buttons or type in fields. It catches mistakes early so users have a smooth experience.
Testing user interactions in Vue
import { mount } from '@vue/test-utils' import Component from './Component.vue' test('description', async () => { const wrapper = mount(Component) await wrapper.find('selector').trigger('event') expect(wrapper.text()).toContain('expected text') })
Use mount to load the component for testing.
Use trigger to simulate user events like clicks or typing.
await wrapper.find('button').trigger('click') expect(wrapper.text()).toContain('Clicked!')
await wrapper.find('input').setValue('Hello') expect(wrapper.find('input').element.value).toBe('Hello')
await wrapper.find('input[type=checkbox]').setChecked(true) expect(wrapper.text()).toContain('Checked!')
This test loads the ButtonClick component, checks that the message is not visible initially, then simulates a button click and confirms the message appears.
/* ButtonClick.vue */ <template> <button @click="clicked = true">Click me</button> <p v-if="clicked">Button was clicked!</p> </template> <script setup> import { ref } from 'vue' const clicked = ref(false) </script> /* ButtonClick.test.js */ import { mount } from '@vue/test-utils' import ButtonClick from './ButtonClick.vue' test('shows message after button click', async () => { const wrapper = mount(ButtonClick) expect(wrapper.text()).not.toContain('Button was clicked!') await wrapper.find('button').trigger('click') expect(wrapper.text()).toContain('Button was clicked!') })
Always wait for Vue to update the DOM after events using await.
Use clear selectors like element tags or classes to find elements.
Test only one interaction per test to keep tests simple and clear.
Testing user interactions means simulating clicks, typing, and other actions.
Use Vue Test Utils mount and trigger to do this.
Check the component output to confirm it reacts correctly.
Practice
trigger in Vue Test Utils when testing user interactions?Solution
Step 1: Understand the role of
triggerThe
triggermethod simulates user events such as clicks or keyboard input on a mounted Vue component.Step 2: Differentiate from other methods
Mounting is done by
mount, checking data is done by assertions, and importing components is unrelated totrigger.Final Answer:
To simulate user events like clicks or typing on components -> Option AQuick Check:
trigger simulates events = B [OK]
- Confusing trigger with mount
- Thinking trigger checks data directly
- Assuming trigger imports components
Solution
Step 1: Identify the correct method to find and trigger
First, find the button element using
find('button'), then calltrigger('click')on it.Step 2: Check each option
wrapper.find('button').click() uses
click()which is not a Vue Test Utils method. wrapper.trigger('click') callstriggeron wrapper, not on the button. wrapper.click('button') uses a non-existentclickmethod.Final Answer:
wrapper.find('button').trigger('click') -> Option BQuick Check:
Find element then trigger event = D [OK]
- Calling trigger on wrapper instead of element
- Using .click() instead of .trigger('click')
- Wrong method order or syntax
const wrapper = mount({
template: `Clicked {{ count }} times`,
data() { return { count: 0 } }
})
await wrapper.find('button').trigger('click')
await wrapper.find('button').trigger('click')
console.log(wrapper.text())What will be logged to the console?
Solution
Step 1: Understand the component's data and event
The button shows the count and increments it by 1 on each click.
Step 2: Count the number of clicks triggered
Two clicks are triggered, so count increases from 0 to 2.
Final Answer:
Clicked 2 times -> Option DQuick Check:
2 clicks increment count to 2 = C [OK]
- Assuming count does not update
- Confusing async behavior
- Ignoring the number of triggers
const wrapper = mount({
template: ``,
data() { return { value: '' } },
methods: {
updateValue(event) { this.value = event.target.value }
}
})
await wrapper.find('input').trigger('input', { target: { value: 'hello' } })
console.log(wrapper.vm.value)What is the output and why?
Solution
Step 1: Understand how trigger passes event data
The
triggermethod emits the event using the second argument as properties of the synthetic event object, soevent.target.valueis set to 'hello'.Step 2: Check why
valueis updatedThe
updateValuemethod readsevent.target.value('hello') and setsthis.value = 'hello'.Final Answer:
hello -> Option AQuick Check:
trigger('input', {target:{value:'hello'}}) updates handler = B [OK]
- Triggering 'input' without payload
- Confusing with v-model inputs (use setValue)
- Confusing input event with change event
template: `{{ message }}
`, data() { return { text: '', message: '' } }, watch: { text(newVal) { this.message = `Typed: ${newVal}` } }
Which test code is correct?
Solution
Step 1: Understand how to simulate typing in Vue Test Utils
The
setValuemethod sets the input value and triggers the input event properly, updating v-model and watchers.Step 2: Evaluate each option's correctness
A uses
setValuecorrectly. B: await wrapper.find('input').trigger('input') expect(wrapper.text()).toContain('Typed: Vue') triggers input without event data so v-model unchanged. C manually sets value but triggers 'change' not updating v-model. D uses invalidsetAttribute.Final Answer:
await wrapper.find('input').setValue('Vue') expect(wrapper.text()).toContain('Typed: Vue') -> Option CQuick Check:
Use setValue to simulate typing = A [OK]
- Using trigger('input') without setValue()
- Manually changing element.value without events
- Using non-existent methods like setAttribute
Ready to prove it?
Pass the test and this pattern moves unknown
