Vue Test Utils カスタムコンポーネントでv-modelを適用したときのテスト
やりたいこと
以下のようなカスタムコンポーネントにv-modelを適用したときに入力値をdataに反映させてテストをする。
sample.vue
<template>
<div>
<formInput v-model="test" type="text"></formInput>
</div>
</template>
<script>
import formInput from '~/components/formInput.vue'
export default {
components: { formInput },
data() {
return {
test: ''
}
}
}
</script>
NG例
input要素だとドキュメントにある通り、以下のようにdataに値を反映することができる。
しかし、上記のようなカスタムコンポーネントでこのコードを実行すると"wrapper.setValue() cannot be called on this element"のようなエラーが表示される。
sample.spec.js
import { shallowMount } from '@vue/test-utils'
import Foo from '~/pages/sample.vue'
const wrapper = shallowMount(Foo)
describe('input要素だとこれでパスする', () => {
test('テストする', () => {
const textInput = wrapper.find('[type="text"]')
textInput.element.value = 'some value'
expect(wrapper.vm.test).toBe('some value')
})
})
解決策
inputイベントを発火させることで、入力値をdataに反映させてテストすることが可能。
sample.spec.js
import { shallowMount } from '@vue/test-utils'
import Foo from '~/pages/sample.vue'
const wrapper = shallowMount(Foo)
describe('カスタムコンポーネントのv-modelでもこれでパスする', () => {
test('テストする', () => {
const textInput = wrapper.find('[type="text"]')
textInput.vm.$emit('input', 'some value')
expect(wrapper.vm.test).toBe('some value')
})
})
参考
こちらにある通り、v-modelはv-onとv-bindを1行で表現したものなので、イベントを発火することでdataを更新することができます。
<input v-model="searchText">
<input :value="searchText" @input="searchText = $event.target.value">
誰かの役に立つことを願って。。