単純なメモ。
<template>
<container>
<button @click="handler">押して</button>
</container>
</template>
<script>
export default {
methods: {
handler() {
// これをテストから直接呼ぶとrender済んでない可能性大
}
}
}
</script>
こんな Vue component があるとする。
端折りまくったテストコードはこんな感じに書けるんだけど、ここで handler() を直接呼んではいけない。
import Komponent from 'komponent.vue'
..
describe('Komponent', () => {
var wrapper
function mountComponent(component) {
return mount(component, {localVue, router, ..})
}
describe('condition', () => {
beforeEach(() => {
wrapper = mountComponent(Komponent)
})
it('wrong example', () => {
wrapper.vm.handler()
})
it('good example', () => {
wrapper.find('button').trigger('click')
})
})
})
どうも直接 handler() を呼ぶと component が render される前に handler() が呼ばれてしまうらしく、少なくとも DOM 上のデータは取得できない。
単純なロジックだけのメソッドならこれでもテスト可能だが、event handler としてのテストをする場合はちゃんと event から呼んであげるのがよいらしい。
で、event を起こすには、まず event を起こしたい要素を特定してあげる。wrapper.find() で特定してあげると DOM wrapper のようなオブジェクトが取得できるので、そいつで event を trigger する1。すると実際に Vue component が render されているような状態で handler() を動作させることができる。
※ ちなみに render という function も export されているのだが、これは @vue/test-utils ではなく @vue/server-test-utils に含まれるものであり、component のテストではなく、render された HTML に対するテストしかできない。mount や shallow の代わりには使えない。
@vue/test-utils を使ったテストはとにかく wrapper を相手にする ↩