跳至内容

条件渲染

Vue 测试工具具有一系列功能,用于渲染组件并对组件状态进行断言,目的是验证组件的行为是否正确。本文将探讨如何渲染组件,以及如何验证组件是否正确渲染内容。

本文也以 短视频 的形式提供。

查找元素

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() 断言个人资料链接的内容

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

  // Here we are implicitly asserting that the
  // element #profile exists.
  const profileLink = wrapper.get('#profile')

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

如果 get() 没有返回与选择器匹配的元素,它将引发错误,并且您的测试将失败。如果找到元素,get() 将返回一个 DOMWrapperDOMWrapper 是 DOM 元素的薄包装器,它实现了 包装器 API - 这就是为什么我们可以执行 profileLink.text() 并访问文本的原因。您可以使用 element 属性访问原始元素。

还有另一种类型的包装器 - VueWrapper - 它从 getComponent 返回,其工作方式相同。

使用 find()exists()

get() 假设元素存在,并在元素不存在时抛出错误。建议将其用于断言存在。

为此,我们使用 find()exists()。下一个测试断言,如果 adminfalse(默认情况下为 false),则管理链接不存在

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

  // Using `wrapper.get` would throw and make the test fail.
  expect(wrapper.find('#admin').exists()).toBe(false)
})

请注意,我们正在调用 .find() 返回的值上的 exists()find()mount() 一样,也返回一个 wrappermount() 有几个额外的函数,因为它包装了 Vue 组件,而 find() 只返回一个普通的 DOM 节点,但许多函数在两者之间共享。一些其他函数包括 classes(),它获取 DOM 节点具有的类,以及用于模拟用户交互的 trigger()。您可以在 此处 找到支持的函数列表。

使用 data

最后的测试是断言当 admintrue 时渲染管理链接。它默认情况下为 false,但我们可以使用 mount() 的第二个参数(挂载选项)来覆盖它。

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

js
test('renders an admin link', () => {
  const wrapper = mount(Nav, {
    data() {
      return {
        admin: true
      }
    }
  })

  // Again, by using `get()` we are implicitly asserting that
  // the element exists.
  expect(wrapper.get('#admin').text()).toEqual('Admin')
})

如果您在 data 中有其他属性,请不要担心 - Vue 测试工具将合并这两个属性。挂载选项中的 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 - find().exists() 一直返回 true - 因为元素仍然在 DOM 中

使用 isVisible()

isVisible() 提供了检查隐藏元素的能力。特别是 isVisible() 将检查以下内容

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

对于所有这些情况,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 中元素的可见性