How can I trigger the 'blur' event while testing a vuejs component?

I'm writing test on a vue component that must call a method when focus is lost.

According to vue-test-utils I should use wrapper.trigger('blur'). But the method is not fired. I suspect that blur isn't the proper event name, since it appears as focusout in the console. But changing the name doesn't solve the problem.

Component:

<template>
    <input @blur="foo" />
</template>
...

Test file:

import { mount } from 'vue-test-utils'
import MyComponent from '../MyComponent'

describe('myComponent', () => {
    const mockFn = jest.fn()
    const wrapper = mount(MyComponent, { mocks: { foo: mockFn } })
    it('fires "foo" on blur', () => {
        wrapper.trigger('blur')
        expect(mockFn).toHaveBeenCalled()
    }

I expected that using wrapper.trigger('blur') would fire foo, which is mocked with mockFn. But mockFn is never called.

Upvotes: 3

Views: 10068

Answers (2)

Narkanister
Narkanister

Reputation: 904

Yes - the component needs to trigger the blur event for you to be able to test it:

<input
  ref="input"
  v-model="text"
  type="text"
  @keyup.enter="toggleEdit($event)"
  @blur="toggleEdit($event)"
/>

Upvotes: 0

I found a solution. The input within MyComponent must trigger the event. Then MyComponent receives the event.

import { mount } from 'vue-test-utils'
import MyComponent from '../MyComponent'

describe('myComponent', () => {
    const mockFn = jest.fn()
    const wrapper = mount(MyComponent, { mocks: { foo: mockFn } })
    it('fires "foo" on blur', () => {
        const childInput = wrapper.find('input')
        childInput.trigger('blur')
        expect(mockFn).toHaveBeenCalled()
    }

Upvotes: 5

Related Questions