はじめに
Vueを用いて検索ボックスを実装することになりました
そこでテストするのに時間がかかったのでまとめておきます
問題
テスト駆動開発で検索ボックスを作ろうとしています
検索ボックスは0.5秒入力がなかった際にemit
が走って親コンポーネントにイベントが飛ぶようにします
テストの設計としては
まず適当な値を入力してemit
が1度も実行されていないことを確認
0.5秒後に再度emit
が実行されたかを検証して1回実行されていればOK
このテストを書こうとして0.5秒
後にテストのアサーションをするのに迷いました
解決方法
以下が最終的にできたコードです
search.spec.ts
import KeywordFilter from '@/KeywordFilter.vue'
import { mount } from '@vue/test-utils'
describe('KeywordFilter', () => {
test('入力を止めたタイミングで検索をする', async (done) => {
const wrapper = mount(keywordFilter)
wrapper.find('.search-box').setValue('test')
await wrapper.vm.$nextTick()
expect(wrapper.emitted().changeKeyword).toBeFalsy()
setTimeout(() => {
expect(wrapper.emitted().changeKeyword.length).toBe(1)
done()
}, 500)
})
})
ポイントは
test('入力を止めたタイミングで検索をする', async (done) => {
ここでasyncの終了を知らせるdone
を引数に渡して
0.5秒たったあとにdone()
を呼ぶことです
これをしないとテストは最初のアサーションだけして0.5秒待たずに終了してしまいます
なので結果的に0.5秒後にemitされることを検証せずにおわりテストは成功してしまいます
おわりに
asyncにdoneというのがあるのを知らなかったので学びになりました
なので記事にしてみました