用 propsData 设置 props

propsData 对于 mountshallowMount 都可以使用。它经常被用于测试从父组件中接受属性(props)的组件。

propsData 会以下面的形式被传入 shallowMountmount 的第二个参数中:

  1. const wrapper = shallowMount(Foo, {
  2. propsData: {
  3. foo: 'bar'
  4. }
  5. })

创建组件

创建一个简单的 <SubmitButton> 组件,有着 msgisAdmin 两种 props。取决于 isAdmin 属性的值,该组件将以如下两种状态中的一种包含一个 <span>

  • Not Authorized:若 isAdmin 为 false (或者没有传入到 props 中)
  • Admin Privileges:若 isAdmin 为 true
  1. <template>
  2. <div>
  3. <span v-if="isAdmin">Admin Privileges</span>
  4. <span v-else>Not Authorized</span>
  5. <button>
  6. {{ msg }}
  7. </button>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. name: "SubmitButton",
  13. props: {
  14. msg: {
  15. type: String,
  16. required: true
  17. },
  18. isAdmin: {
  19. type: Boolean,
  20. default: false
  21. }
  22. }
  23. }
  24. </script>

第一个测试

我们将对用户没有 admin 权限时的 msg 做一个断言:

  1. import { shallowMount } from '@vue/test-utils'
  2. import SubmitButton from '@/components/SubmitButton.vue'
  3. describe('SubmitButton.vue', () => {
  4. it("displays a non authorized message", () => {
  5. const msg = "submit"
  6. const wrapper = shallowMount(SubmitButton,{
  7. propsData: {
  8. msg: msg
  9. }
  10. })
  11. console.log(wrapper.html())
  12. expect(wrapper.find("span").text()).toBe("Not Authorized")
  13. expect(wrapper.find("button").text()).toBe("submit")
  14. })
  15. })

yarn test:unit 运行测试。结果是:

  1. PASS tests/unit/SubmitButton.spec.js
  2. SubmitButton.vue
  3. displays a non authorized message (15ms)

console.log(wrapper.html()) 的结果也被打印出来了:

  1. <div>
  2. <span>Not Authorized</span>
  3. <button>
  4. submit
  5. </button>
  6. </div>

可见 msg prop 已经被处理并且结果也渲染正常。

第二个测试

让我们对另一种可能的状态作出断言。当 isAdmintrue 时:

  1. import { shallowMount } from '@vue/test-utils'
  2. import SubmitButton from '@/components/SubmitButton.vue'
  3. describe('SubmitButton.vue', () => {
  4. it('displays a admin privileges message', () => {
  5. const msg = "submit"
  6. const isAdmin = true
  7. const wrapper = shallowMount(SubmitButton,{
  8. propsData: {
  9. msg,
  10. isAdmin
  11. }
  12. })
  13. console.log(wrapper.html())
  14. expect(wrapper.find("span").text()).toBe("Admin Privileges")
  15. expect(wrapper.find("button").text()).toBe("submit")
  16. })
  17. })

yarn test:unit 运行测试并检查结果:

  1. PASS tests/unit/SubmitButton.spec.js
  2. SubmitButton.vue
  3. displays a admin privileges message (4ms)

同样用 console.log(wrapper.html()) 输出了结果:

  1. <div>
  2. <span>Admin Privileges</span>
  3. <button>
  4. submit
  5. </button>
  6. </div>

可见 isAdmin 被用来渲染了正确的 <span> 元素。

重构测试

让我们遵循 “Don’t Repeat Yourself” 的 DRY 原则来重构测试。因为所有测试都通过了,我们就能放心大胆地重构了。只要重构后测试仍然通过,就能确保我们没有破坏任何东西。

用工厂函数重构

在几个测试中我们都调用了 shallowMount 并随后传入一个相似的 propsData 对象。我们可以讲这件事重构为一个工厂函数。一个工厂函数只是一个返回单个对象的简单函数 — 它 制造 对象,这就是其名为 “工厂” 的原因。

  1. const msg = "submit"
  2. const factory = (propsData) => {
  3. return shallowMount(SubmitButton, {
  4. propsData: {
  5. msg,
  6. ...propsData
  7. }
  8. })
  9. }

以上就是一个将会 shallowMount 一个 SubmitButton 组件的函数。可以传入任何属性以改变 factory 的首个参数。让我们用这个工厂函数 DRY 测试起来。

  1. describe("SubmitButton", () => {
  2. describe("has admin privileges", ()=> {
  3. it("renders a message", () => {
  4. const wrapper = factory()
  5. expect(wrapper.find("span").text()).toBe("Not Authorized")
  6. expect(wrapper.find("button").text()).toBe("submit")
  7. })
  8. })
  9. describe("does not have admin privileges", ()=> {
  10. it("renders a message", () => {
  11. const wrapper = factory({ isAdmin: true })
  12. expect(wrapper.find("span").text()).toBe("Admin Privileges")
  13. expect(wrapper.find("button").text()).toBe("submit")
  14. })
  15. })
  16. })

再次运行测试。所有事情仍然通过。

  1. PASS tests/unit/SubmitButton.spec.js
  2. SubmitButton
  3. has admin privileges
  4. renders a message (26ms)
  5. does not have admin privileges
  6. renders a message (3ms)

正因为我们有了良好的测试套件,所以就可以容易而放心的重构了。

总结

  • 通过在加载一个组件时传递 propsData,就可以设置 props 以用于测试
  • 工厂函数可以被用来 DRY 你的测试
  • 除了 propsData,你也可以查阅 setProps测试 Props - 图1 以在测试中设置属性值