跳至内容

编写易于测试的组件

Vue Test Utils 帮助你编写 Vue 组件的测试。但是,VTU 只能做这么多。

以下是编写更易于测试的代码以及编写有意义且易于维护的测试的建议列表。

以下列表提供一般性指导,在常见情况下可能会有所帮助。

不要测试实现细节

从用户的角度考虑输入和输出。大体上,这是编写 Vue 组件测试时应考虑的所有事项。

输入示例
交互点击、输入... 任何“人类”交互
道具组件接收的参数
数据流来自 API 调用的传入数据、数据订阅...
输出示例
DOM 元素渲染到文档的任何可观察节点
事件发射的事件(使用 $emit
副作用例如 console.log 或 API 调用

其他所有内容都是实现细节.

请注意,此列表不包括内部方法、中间状态甚至数据等元素。

经验法则是,测试不应该在重构时中断,也就是说,当我们更改其内部实现而不更改其行为时。如果发生这种情况,测试可能依赖于实现细节。

例如,假设一个基本的 Counter 组件,它有一个按钮用于增加计数器。

vue
<template>
  <p class="paragraph">Times clicked: {{ count }}</p>
  <button @click="increment">increment</button>
</template>

<script>
export default {
  data() {
    return { count: 0 }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>

我们可以编写以下测试

js
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'

test('counter text updates', async () => {
  const wrapper = mount(Counter)
  const paragraph = wrapper.find('.paragraph')

  expect(paragraph.text()).toBe('Times clicked: 0')

  await wrapper.setData({ count: 2 })

  expect(paragraph.text()).toBe('Times clicked: 2')
})

请注意,我们在这里更新了其内部数据,并且我们还依赖于(从用户的角度来看)诸如 CSS 类之类的细节。

提示

请注意,更改数据或 CSS 类名都会导致测试失败。但是,组件仍然按预期工作。这被称为误报

相反,以下测试试图坚持上述输入和输出

js
import { mount } from '@vue/test-utils'

test('text updates on clicking', async () => {
  const wrapper = mount(Counter)

  expect(wrapper.text()).toContain('Times clicked: 0')

  const button = wrapper.find('button')
  await button.trigger('click')
  await button.trigger('click')

  expect(wrapper.text()).toContain('Times clicked: 2')
})

诸如 Vue Testing Library 之类的库是基于这些原则构建的。如果你对这种方法感兴趣,请务必查看它。

构建更小、更简单的组件

经验法则是,如果组件的功能更少,那么它就更容易测试。

创建更小的组件将使它们更具可组合性,也更容易理解。以下是使组件更简单的建议列表。

提取 API 调用

通常,你将在整个应用程序中执行多个 HTTP 请求。从测试的角度来看,HTTP 请求为组件提供输入,组件也可以发送 HTTP 请求。

提示

如果你不熟悉测试 API 调用,请查看 发出 HTTP 请求 指南。

提取复杂方法

有时,组件可能包含一个复杂的方法、执行繁重的计算或使用多个依赖项。

这里的建议是提取此方法并将其导入组件。这样,你就可以使用 Jest 或任何其他测试运行器独立测试该方法。

这还有助于最终得到一个更容易理解的组件,因为复杂逻辑封装在另一个文件中。

此外,如果复杂方法难以设置或速度很慢,你可能希望对其进行模拟,以使测试更简单、更快。关于 发出 HTTP 请求 的示例就是一个很好的例子——axios 是一个相当复杂的库!

在编写组件之前编写测试

如果你事先编写测试,你就无法编写不可测试的代码!

我们的 速成课程 提供了在代码之前编写测试如何导致可测试组件的示例。它还有助于你检测和测试边缘情况。