两种渲染方式

vue-test-utils 提供了两种方式用于渲染,或者说 加载(mount) 一个组件 — mountshallowMount。一个组件无论使用这两种方法的哪个都会返回一个 wrapper,也就是一个包含了 Vue 组件的对象,辅以一些对测试有用的方法。

让我们从两个简单的组件开始:

  1. const Child = Vue.component("Child", {
  2. name: "Child",
  3. template: "<div>Child component</div>"
  4. })
  5. const Parent = Vue.component("Parent", {
  6. name: "Parent",
  7. template: "<div><child /></div>"
  8. })

先来渲染 Child 并调用由 vue-test-utils 提供的用以核查置标语言的 html 方法。

  1. const shallowWrapper = shallowMount(Child)
  2. const mountWrapper = mount(Child)
  3. console.log(shallowWrapper.html())
  4. console.log(mountWrapper.html())

mountWrapper.html()shallowWrapper.html() 都产生了如下输出:

  1. <div>Child component</div>

此次并没有差别。换作 Parent 又如何呢?

  1. const shallowWrapper = shallowMount(Parent)
  2. const mountWrapper = mount(Parent)
  3. console.log(shallowWrapper.html())
  4. console.log(mountWrapper.html())

mountWrapper.html() 现在产生了:

  1. <div><div>Child component</div></div>

这完整地渲染了 ParentChild 的标记。而 shallowWrapper.html() 产生了如下输出:

  1. <div><vuecomponent-stub></vuecomponent-stub></div>

原本 <Child /> 应该出现的地方被替换成了 <vuecomponent-stub />shallowMount 会渲染常规的 HTML 元素,但将用 stub 替换掉 Vue 组件。

一个 stub 就是一种替代真实组件的 “假的” 对象

这会很管用。想象一下要测试你的 App.vue 组件,看起来是这样的:

  1. <template>
  2. <div>
  3. <h1>My Vue App</h1>
  4. <fetch-data />
  5. </div>
  6. </template>

并且我们只想测试 <h1>My Vue App</h1> 被正确地渲染了。但同时我们也有一个 <fetch-data> 组件,该组件在其 mounted 生命周期钩子中向外部 API 发起一个请求。

如果我们用了 mount,尽管我们只想断言一些文本被渲染,但 <fetch-data /> 也将发起 API 请求。这将拖慢测试并容易出错。所以,我们 stub 掉外部依赖。通过使用 shallowMount<fetch-data /> 将会被替换为一个 <vuecomponent-stub />,并且 API 调用也不会被初始化了。