Skip to content
该翻译已同步到了 的版本,其对应的 commit hash 是 7c55128

条件渲染

Vue Test Utils 提供了一系列功能,用于渲染组件并对其状态进行断言,以验证其是否正常工作。本文将探讨如何渲染组件,以及如何验证组件是否正确渲染内容。

这篇文章也提供了短视频版本。

查找元素

Vue 最基础的特性之一是能够使用 v-if 动态地插入和移除元素。让我们看看如何测试一个使用了 v-if 的组件。

vue
<!-- 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,我们还会显示指向管理中心的链接。这里有三个我们需要验证的场景:

  1. 显示 /profile 链接。
  2. 当用户是管理员时,显示 /admin 链接。
  3. 当用户不是管理员时,不显示 /admin 链接。

使用 get()

wrapper 有一个 get() 方法,用于查找存在的元素。它使用 querySelector 语法。

我们可以使用 get() 来断言 profile 链接的文本内容:

js
test('renders a profile link', () => {
  const wrapper = mount(Nav)

  // 这里我们隐式断言 #profile 元素存在。
  const profileLink = wrapper.get('#profile')

  expect(profileLink.text()).toEqual('My Profile')
})

如果 get() 没有找到匹配选择器的元素,它会抛出错误,测试将会失败。如果找到了元素,get() 返回一个 DOMWrapperDOMWrapper 是一个轻量级的 DOM 元素包装,它实现了 Wrapper API,这就是为什么我们能够使用 profileLink.text() 来访问文本内容。你可以通过 element 属性访问原始元素。

还有另一种封装类型:VueWrapper,它由 getComponent 返回,工作方式相同。

使用 find()exists()

get() 基于元素存在的假设来工作,当元素不存在时会抛出错误。因此,不推荐使用它来断言元素是否存在。

为此,我们使用 find()exists()。下面的测试用例断言:如果 adminfalse(默认值),admin 链接不会出现:

js
test('does not render an admin link', () => {
  const wrapper = mount(Nav)

  // 使用 `wrapper.get` 会抛出错误并导致测试失败。
  expect(wrapper.find('#admin').exists()).toBe(false)
})

请注意,我们在 .find() 返回的值上调用了 exists()find()mount() 一样,也会返回一个 wrappermount() 有一些额外的方法,因为它包装的是 Vue 组件,而 find() 只返回普通的 DOM 节点,但它们之间有许多共享的方法。其他方法还包括 classes(),用于获取 DOM 节点的 class 属性,以及用于模拟用户交互的 trigger()。你可以在这里找到支持的方法列表。

检查元素可见性

有时你可能只想隐藏/显示一个元素,同时将其保留在 DOM 中。Vue 为这种场景提供了 v-show 指令。(你可以在这里查阅 v-ifv-show 的区别。)

使用 v-show 的组件如下所示:

vue
<!-- Nav.vue -->
<script setup>
import { ref } from 'vue'

const shouldShowDropdown = ref(false)
<script>

<template>
  <nav>
    <a id="user" href="/profile">My Profile</a>
    <ul v-show="shouldShowDropdown" id="user-dropdown">
      <!-- dropdown content -->
    </ul>
  </nav>
</template>

在这种场景下,元素虽然不可见但始终被渲染。get()find() 将始终返回一个 Wrapper——因为该元素仍然在 DOM 中,所以 find() 结合 .exists() 始终返回 true

使用 isVisible()

isVisible() 提供了检查隐藏元素的能力。具体来说,isVisible() 会检查:

  • 元素或其祖先元素是否具有 display: nonevisibility: hiddenopacity: 0 样式
  • 元素或其祖先是否位于折叠的 <details> 标签内
  • 元素本身或其祖先元素是否有 hidden attribute

在以上任一情况下,isVisible() 都会返回 false。

使用 v-show 进行测试的场景如下:

js
test('does not show the user dropdown', () => {
  const wrapper = mount(Nav)

  expect(wrapper.get('#user-dropdown').isVisible()).toBe(false)
})

总结

  • 使用 find() 结合 exists() 验证元素是否在于 DOM 中。
  • 如果你确认元素存在于 DOM 中,就使用 get()
  • 可以使用 data 挂载选项设置组件的默认值。
  • 使用 get()isVisible() 验证在 DOM 中元素的可见性。

Released under the MIT License.