條件渲染
Vue Test Utils 提供多種功能來渲染元件並對元件狀態進行斷言,目的是驗證元件行為是否正確。這篇文章會介紹如何渲染元件,以及如何驗證元件內容是否正確顯示。
這篇文章也有短影片版本。
查找元素
Vue 最基本的功能之一就是可以用 v-if 動態插入或移除元素。來看看如何測試一個使用 v-if 的元件。
<!-- Nav.vue -->
<script setup>
import { ref } from 'vue'
const admin = ref(false)
</script>
<template>
<nav>
<a id="profile" href="/profile">My Profile</a>
<a v-if="admin" id="admin" href="/admin">Admin</a>
</nav>
</template>
在 <Nav> 元件中,會顯示一個連到使用者個人頁的連結。如果 admin 為 true,還會多顯示一個連到管理頁的連結。有三種情境需要驗證:
- /profile 連結應該要顯示。
- 當使用者是 admin 時,/admin 連結應該要顯示。
- 當使用者不是 admin 時,/admin 連結不應該顯示。
使用 get()
wrapper 有一個 get() 方法可以搜尋已存在的元素,語法和 querySelector 一樣。
我們可以用 get() 來斷言 profile 連結的內容:
test('renders a profile link', () => {
const wrapper = mount(Nav)
// 這裡隱含斷言 #profile 元素一定存在
const profileLink = wrapper.get('#profile')
expect(profileLink.text()).toEqual('My Profile')
})
如果 get() 找不到符合 selector 的元素,會丟出錯誤,測試就會失敗。get() 如果找到元素,會回傳一個 DOMWrapper。DOMWrapper 是包裹 DOM 元素的薄包裝,實作了 Wrapper API,所以我們可以用 profileLink.text() 取得文字內容。你也可以用 element 屬性取得原生 DOM 元素。
還有另一種 wrapper 叫 VueWrapper,是 getComponent 回傳的,使用方式類似。
使用 find() 和 exists()
get() 假設元素一定存在,找不到就會丟錯,不建議用來斷言元素是否存在。
要斷言元素是否存在,請用 find() 搭配 exists()。下面這個測試斷言 admin 預設為 false 時,admin 連結不會出現:
test('does not render an admin link', () => {
const wrapper = mount(Nav)
// 用 wrapper.get 會丟錯,讓測試失敗
expect(wrapper.find('#admin').exists()).toBe(false)
})
注意我們對 find() 回傳的值呼叫 exists()。find() 跟 mount() 一樣會回傳一個 wrapper。mount() 包的是 Vue 元件,所以有多一些方法,find() 回傳的是一般 DOM 節點,但兩者有很多共用方法。像 classes() 可以取得 DOM 節點的 class,trigger() 可以模擬使用者互動。更多方法請參考官方文件。
使用 data
最後一個測試是驗證 admin 為 true 時,admin 連結會顯示。預設是 false,但我們可以用 mount() 的第二個參數(mounting options)來覆蓋。
對於 data,可以用 data 這個選項:
test('renders an admin link', () => {
const wrapper = mount(Nav, {
data() {
return {
admin: true
}
}
})
// 用 get() 隱含斷言元素一定存在
expect(wrapper.get('#admin').text()).toEqual('Admin')
})
如果 data 裡有其他屬性不用擔心,Vue Test Utils 會自動合併,mounting options 的 data 會覆蓋預設值。
想了解更多 mounting options,請參考 Passing Data 或官方文件。