vue-test-utils常用技巧6-10丨技术开发分享录

vue-test-utils常用技巧6-10

{{ detail.nickname }}

转载 翻译 {{ formatTime(detail.create_time) }} 字数 {{ detail.content && detail.content.length }} 阅读 {{ detail.read_num }} {{ formatTag(v) }}

"## 一、 操作组件状态\n\n你可以在包裹器上用 setData 或 setProps 方法直接操作组件状态:\n\n```\nit('manipulates state', async () => {\n  await wrapper.setData({ count: 10 })\n\n  await wrapper.setProps({ foo: 'bar' })\n})\n```\n\n## 二、仿造 Prop\n\n你可以使用 Vue 在内置 propsData 选项向组件传入 prop:\n\n```\nimport { mount } from '@vue/test-utils'\n\nmount(Component, {\n  propsData: {\n    aProp: 'some value'\n  }\n})\n```\n\n你也可以用 wrapper.setProps({}) 方法更新这些已经挂载的组件的 prop:\n\n## 三、仿造 Transitions\n\n尽管在大多数情况下使用 `await Vue.nextTick()` 效果很好,但是在某些情况下还需要一些额外的工作。这些问题将在 vue-test-utils 移出 beta 版本之前解决。其中一个例子是 Vue 提供的带有 `<transition>` 包装器的单元测试组件。\n\n```\n<template>\n  <div>\n    <transition>\n      <p v-if=\"show\">Foo</p>\n    </transition>\n  </div>\n</template>\n\n<script>\nexport default {\n  data() {\n    return {\n      show: true\n    }\n  }\n}\n</script>\n```\n\n您可能想编写一个测试用例来验证是否显示了文本 Foo ,在将 show 设置为 false 时,不再显示文本 Foo。测试用例可以这么写:\n\n```\ntest('should render Foo, then hide it', async () => {\n  const wrapper = mount(Foo)\n  expect(wrapper.text()).toMatch(/Foo/)\n\n  wrapper.setData({\n    show: false\n  })\n  await wrapper.vm.$nextTick()\n\n  expect(wrapper.text()).not.toMatch(/Foo/)\n})\n```\n\n实际上,尽管我们调用了 `setData` 方法,然后等待 `nextTick` 来确保 DOM 被更新,但是该测试用例仍然失败了。这是一个已知的问题,与 Vue 中 `<transition>` 组件的实现有关,我们希望在 1.0 版之前解决该问题。在目前情况下,有一些解决方案:\n\n**使用 `transitionStub`**\n\n```\nconst transitionStub = () => ({\n  render: function(h) {\n    return this.$options._renderChildren\n  }\n})\n\ntest('should render Foo, then hide it', async () => {\n  const wrapper = mount(Foo, {\n    stubs: {\n      transition: transitionStub()\n    }\n  })\n  expect(wrapper.text()).toMatch(/Foo/)\n\n  wrapper.setData({\n    show: false\n  })\n  await wrapper.vm.$nextTick()\n\n  expect(wrapper.text()).not.toMatch(/Foo/)\n})\n```\n\n**避免 `setData`**\n\n另一种选择是通过编写两个测试来简单地避免使用 `setData`,这要求我们在使用 `mount` 或者 `shallowMount` 时需要指定一些选项:\n\n```\ntest('should render Foo', async () => {\n  const wrapper = mount(Foo, {\n    data() {\n      return {\n        show: true\n      }\n    }\n  })\n\n  expect(wrapper.text()).toMatch(/Foo/)\n})\n\ntest('should not render Foo', async () => {\n  const wrapper = mount(Foo, {\n    data() {\n      return {\n        show: false\n      }\n    }\n  })\n\n  expect(wrapper.text()).not.toMatch(/Foo/)\n})\n```\n\n## 四、应用全局的插件和混入\n\n有些组件可能依赖一个全局插件或混入 (mixin) 的功能注入,比如 vuex 和 vue-router。\n\n如果你在为一个特定的应用撰写组件,你可以在你的测试入口处一次性设置相同的全局插件和混入。但是有些情况下,比如测试一个可能会跨越不同应用共享的普通的组件套件的时候,最好还是在一个更加隔离的设置中测试你的组件,不对全局的 Vue 构造函数注入任何东西。我们可以使用 `createLocalVue` 方法来存档它们:\n\n```\nimport { createLocalVue, mount } from '@vue/test-utils'\n\n// 创建一个扩展的 `Vue` 构造函数\nconst localVue = createLocalVue()\n\n// 正常安装插件\nlocalVue.use(MyPlugin)\n\n// 在挂载选项中传入 `localVue`\nmount(Component, {\n  localVue\n})\n```\n\n>[warning] 注意:有些插件会为全局的 Vue 构造函数添加只读属性,比如 Vue Router。这使得我们无法在一个 localVue 构造函数上二次安装该插件,或伪造这些只读属性。\n\n## 五、仿造注入\n\n另一个注入 `prop` 的策略就是简单的仿造它们。你可以使用 `mocks` 选项:\n\n```\nimport { mount } from '@vue/test-utils'\n\nconst $route = {\n  path: '/',\n  hash: '',\n  params: { id: '123' },\n  query: { q: 'hello' }\n}\n\nmount(Component, {\n  mocks: {\n    // 在挂载组件之前\n    // 添加仿造的 `$route` 对象到 Vue 实例中\n    $route\n  }\n})\n```"
PS:写作不易,如要转裁,请标明转载出处。

如果此篇对您有帮助,可小额赞助,以兹鼓励!

猜你想看