親子間での値の受け渡しとテスト
プロダクトコード
子コンポーネント①(propsでnameを親から受け取り、ただemitする)
<template>
<div>
<Button @click="emitChildData">{{ name }}</Button>
</div>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue'
export default Vue.extend({
name: 'InputChild',
props: {
name: {
type: String as PropType<string>,
},
},
methods: {
emitChildData(): void {
this.$emit('childEmit')
},
},
})
</script>
ボタンクリックでemitChildDataが動き、(‘childEmit’)をemitする
子コンポーネント②(propsでnameを親から受け取り、引数付きでemitする)
<template>
<div>
<Button @click="emitChildDataWithArgument">{{ name }}</Button>
</div>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue'
// import { SelectOptions} from '~/types/SelectOptions'
export default Vue.extend({
name: 'InputChild',
props: {
name: {
type: String as PropType<string>,
required: false,
},
},
data(): { emitData: string } {
return { emitData: 'test' }
},
methods: {
emitChildDataWithArgument(): void {
this.$emit('childEmitWithArgument', this.emitData)
},
},
})
</script>
ボタンクリックでemitChildDataWithArgumentが動き、(‘childEmitWithArgumen’)を引数付きでemitする
親コンポーネント(子①、子②にnameを渡す)
<template>
<div>
<InputChild name="emitChildData" @childEmit="emitData"></InputChild>
<InputChildWithArgument
name="emitChildDataWithArgument"
@childEmitWithArgument="emitDataWithArgument"
></InputChildWithArgument>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import InputChild from '@/components/atoms/InputChild.vue'
import InputChildWithArgument from '@/components/atoms/InputChildWithArgument.vue'
export default Vue.extend({
components: {
InputChild,
InputChildWithArgument,
},
data(): {
testData: string
} {
return {
testData: '',
}
},
methods: {
emitData() {
console.log(`getChildEmit ${this.testData}`)
},
emitDataWithArgument(value: string) {
this.testData = value
console.log(`getChildEmitWithArgument ${this.testData}`)
},
},
})
</script>
<style></style>
親コンポーネントの@○○=”××”で ○○がemitされたら××を実行という意味になる。@clickのemit版みたいな感じ。
childEmitWithArgumentの方はemitDataWithArgument(value:string)で引数付きで呼び出せる
テストコード
子コンポーネント①テスト
import { shallowMount } from '@vue/test-utils'
import InputChild from '@/components/atoms/InputChild.vue'
const spy = jest.fn()
describe('emit test', () => {
it('childEmitWithArgumentがemitされていることのテスト', () => {
const wrapper = shallowMount(InputChild, {
mocks: {
$emit: spy,
},
propsData: {
name: 'testName',
},
})
wrapper.find('Button').trigger('click')
expect(spy).toHaveBeenCalledWith('childEmit')
expect(wrapper.text()).toBe('testName')
})
})
ボタンをクリックしたを擬似的に実行し、$emitにspyを置くことでemitされた値が読み取れるようになる。
クリックでchildEmitをemitしているのでexpect(spy).toHaveBeenCalledWith(‘childEmit’)で何がemitされているかを検証
expect(wrapper.text()).toBe(‘testName’)はpropsで何が渡されているのかを検証している。propsはmountする際にmockしている。
子コンポーネント②テスト
import { shallowMount } from '@vue/test-utils'
import inputChildWithArgument from '@/components/atoms/InputChildWithArgument.vue'
const spy = jest.fn()
describe('emit test', () => {
it('childEmitがemitされていることのテスト', () => {
const wrapper = shallowMount(inputChildWithArgument, {
mocks: {
$emit: spy,
},
propsData: {
name: 'test1',
},
})
wrapper.find('Button').trigger('click')
expect(spy).toHaveBeenCalledWith('childEmitWithArgument', 'test')
})
})
ほぼ子コンポーネント①テストと同じ
expect(spy).toHaveBeenCalledWith(‘childEmitWithArgument’, ‘test’)で’test’が引数にあることを確認している。
親コンポーネントテスト
import { shallowMount } from '@vue/test-utils'
import inputParent from '@/pages/InputParent.vue'
import inputChildWithArgument from '@/components/atoms/inputChildWithArgument.vue'
describe('emit test', () => {
it('childEmitがemitされていることのテスト', async () => {
const wrapper = shallowMount(inputParent)
await wrapper
.findComponent(inputChildWithArgument)
.vm.$emit('childEmitWithArgument', 'test')
expect(wrapper.vm.$data.testData).toEqual('test')
})
})
今度はinputChildWithArgument(子コンポーネント)を使ってemitさせるところまでを行い、親のdataにあるtestDataがmethodsのemitDataWithArgumentと挙動が一致しているかを確認しています。
emitDataWithArgumentではtestDataを引数に変更する処理が入っているので、
await wrapper
.findComponent(inputChildWithArgument)
.vm.$emit(‘childEmitWithArgument’, ‘test’)で第二引数のtestを渡し、親コンポーネント側でtestDataが’test’になっているかを確認しています。
emitDataWithArgumentが呼ばれていることを確認するためにhaveBeenCalled()でexpectしたいのですが、vueコンポーネントのmethodsをspyするやり方がわかりませんでした。どなたかご存知であればコメント頂けると幸いです。
コメントを残す