Vue-test-utilsのpropsDataの基本的な使い方
最新版はこちらで、Vue.jsのテストの書き方についてのハンドブックを公開させてもらっています。
この記事を読むと
- テスト時にコンポーネントをwrapするときの引数の
propsData
に詳しくなる - テストの実践的なリファクタリングが学べる
弊社では、テストのリファクタリングは factory関数
というものを作成して行っているので、興味あるかたはぜひ使ってみてください。
propsDataの基本的な使い方
propsData
は基本的に mount
や shallowMount
とともに使うことができ、 propsData
は親コンポーネントから props
として渡されたものとしてテストで使用できます。
第二引数のオブジェクトの中に書くことができますが、基本的な書き方は次の通りです。
const wrapper = shallowMount(Foo, {
propsData: {
foo: 'bar'
}
})
コンポーネントの作成とテスト
SubmitButton.vue
2つの props
を持つ簡単なコンポーネントを作成する。
<template>
<div>
<span v-if="isAdmin">管理者権限を実行する</span>
<span v-else>権限がありません</span>
<button>
{{ msg }}
</button>
</div>
</template>
<script>
export default {
name: "SubmitButton",
props: {
msg: {
type: String,
required: true
},
isAdmin: {
type: Boolean,
default: false
}
}
}
</script>
最初のテスト
権限がない状態でのメッセージを検証していく。
import { shallowMount } from '@vue/test-utils'
import SubmitButton from '@/components/SubmitButton.vue'
describe('SubmitButton.vue', () => {
it('権限がない状態のメッセージを表示する', () => {
const msg = "送信する"
const wrapper = shallowMount(SubmitButton,{
propsData: {
msg: msg
}
})
console.log(wrapper.html())
expect(wrapper.find("span").text()).toBe("権限がありません")
expect(wrapper.find("button").text()).toBe("送信する")
})
})
テスト結果
PASS tests/unit/SubmitButton.spec.js
SubmitButton.vue
✓ 権限がない状態のメッセージを表示する (15ms)
console.logの出力結果
<div>
<span>権限がありません</span>
<button>
送信する
</button>
</div>
props
で渡された msg
がきちんと描画されていることがわかります。
2つ目のテスト
権限がある状態 ( isAdmin
が true ) でのメッセージを検証していく。
SubmitButton.spec.js
import { shallowMount } from '@vue/test-utils'
import SubmitButton from '@/components/SubmitButton.vue'
describe('SubmitButton.vue', () => {
it('権限がある状態のメッセージを表示する', () => {
const msg = "送信する"
const isAdmin = true
const wrapper = shallowMount(SubmitButton,{
propsData: {
msg,
isAdmin
}
})
expect(wrapper.find("span").text()).toBe("管理者権限を実行する")
expect(wrapper.find("button").text()).toBe("送信する")
})
})
テスト結果
PASS tests/unit/SubmitButton.spec.js
SubmitButton.vue
✓ 権限がある状態のメッセージを表示する (4ms)
console.logの出力結果
<div>
<span>管理者権限を実行する</span>
<button>
送信する
</button>
</div>
props
で渡された isAdmin
によって <span>
の中がきちんと描画されていることがわかります。
テストのリファクタリング
Don't repeat yourself
の原則に従って従ってテストをリファクタリングしていきましょう。テストがPassしているのでリファクタリングも怖くありません。
factory関数
テストの度に shallowMount
を呼び出し同じような propsData
を渡しているので、factory関数でリファクタリングしたいと思います。
const msg = "送信する"
const factory = (propsData) => {
return shallowMount(SubmitButton, {
propsData: {
msg,
...propsData
}
})
}
呼び出すたびに shallowMount
で wrap してくれる factory 関数ができました。これを使ってテストをDRYにしていきましょう。
describe("管理者あり", ()=> {
it("メッセージを表示する", () => {
const wrapper = factory()
expect(wrapper.find("span").text()).toBe("権限がありません")
expect(wrapper.find("button").text()).toBe("送信する")
})
})
describe("管理者なし", ()=> {
it("メッセージを表示する", () => {
const wrapper = factory({isAdmin: true})
expect(wrapper.find("span").text()).toBe("管理者権限を実行する")
expect(wrapper.find("button").text()).toBe("送信する")
})
})
さてテストを見ていきたいと思います。まだテストはGreenでPASSしています。
PASS tests/unit/SubmitButton.spec.js
SubmitButton.vue
リファクタリング
管理者あり
✓ メッセージを表示する (5ms)
管理者なし
✓ メッセージを表示する (2ms)
テストがあることで、変更やリファクタリングが怖くなくなりました。
まとめ
-
propsData
はコンポーネントをマウントするときに引数として渡し、props
として利用できる - factory関数を定義することでテストがDRYにかける
-
propsData
を使わずにsetProps
を使えばプロパティを強制的に更新することもできる