Skip to content
该翻译已同步到了 的版本,其对应的 commit hash 是 7c55128
同时该文档仍处于校对中,如有任何疑问或想参与校对工作,请移步这里了解更多。

条件渲染

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

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

查找元素

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

js
const Nav = {
  template: `
    <nav>
      <a id="profile" href="/profile">My Profile</a>
      <a v-if="admin" id="admin" href="/admin">Admin</a>
    </nav>
  `,
  data() {
    return {
      admin: false
    }
  }
}

<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()。你可以在这里找到支持的方法列表。

使用 data

最后一个测试是断言当 admintrue 时,会渲染 admin 链接。它的默认值是 false,但我们可以使用 mount() 的第二个参数,即挂载选项来覆盖它。

对于 data,我们使用恰如其名的 data 选项:

js
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 会将两者合并。挂载选项中的 data 会优先于任何默认值。

要了解其他挂载选项,请参见传递数据挂载选项

检查元素可见性

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

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

js
const Nav = {
  template: `
    <nav>
      <a id="user" href="/profile">My Profile</a>
      <ul v-show="shouldShowDropdown" id="user-dropdown">
        <!-- dropdown content -->
      </ul>
    </nav>
  `,
  data() {
    return {
      shouldShowDropdown: false
    }
  }
}

在这种场景下,元素虽然不可见但始终被渲染。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.