# 用 propsData 设置 props
propsData
对于 mount
和 shallowMount
都可以使用。它经常被用于测试从父组件中接受属性(props)的组件。
propsData
会以下面的形式被传入 shallowMount
或 mount
的第二个参数中:
const wrapper = shallowMount(Foo, {
propsData: {
foo: 'bar'
}
})
# 创建组件
创建一个简单的 <SubmitButton>
组件,有着 msg
和 isAdmin
两种 props。取决于 isAdmin
属性的值,该组件将以如下两种状态中的一种包含一个 <span>
:
Not Authorized
:若isAdmin
为 false (或者没有传入到 props 中)Admin Privileges
:若isAdmin
为 true
<template>
<div>
<span v-if="isAdmin">Admin Privileges</span>
<span v-else>Not Authorized</span>
<button>
{{ msg }}
</button>
</div>
</template>
<script>
export default {
name: "SubmitButton",
props: {
msg: {
type: String,
required: true
},
isAdmin: {
type: Boolean,
default: false
}
}
}
</script>
# 第一个测试
我们将对用户没有 admin 权限时的 msg 做一个断言:
import { shallowMount } from '@vue/test-utils'
import SubmitButton from '@/components/SubmitButton.vue'
describe('SubmitButton.vue', () => {
it("displays a non authorized message", () => {
const msg = "submit"
const wrapper = shallowMount(SubmitButton,{
propsData: {
msg: msg
}
})
console.log(wrapper.html())
expect(wrapper.find("span").text()).toBe("Not Authorized")
expect(wrapper.find("button").text()).toBe("submit")
})
})
用 yarn test:unit
运行测试。结果是:
PASS tests/unit/SubmitButton.spec.js
SubmitButton.vue
✓ displays a non authorized message (15ms)
console.log(wrapper.html())
的结果也被打印出来了:
<div>
<span>Not Authorized</span>
<button>
submit
</button>
</div>
可见 msg
prop 已经被处理并且结果也渲染正常。
# 第二个测试
让我们对另一种可能的状态作出断言。当 isAdmin
为 true
时:
import { shallowMount } from '@vue/test-utils'
import SubmitButton from '@/components/SubmitButton.vue'
describe('SubmitButton.vue', () => {
it('displays a admin privileges message', () => {
const msg = "submit"
const isAdmin = true
const wrapper = shallowMount(SubmitButton,{
propsData: {
msg,
isAdmin
}
})
console.log(wrapper.html())
expect(wrapper.find("span").text()).toBe("Admin Privileges")
expect(wrapper.find("button").text()).toBe("submit")
})
})
用 yarn test:unit
运行测试并检查结果:
PASS tests/unit/SubmitButton.spec.js
SubmitButton.vue
✓ displays a admin privileges message (4ms)
同样用 console.log(wrapper.html())
输出了结果:
<div>
<span>Admin Privileges</span>
<button>
submit
</button>
</div>
可见 isAdmin
被用来渲染了正确的 <span>
元素。
# 重构测试
让我们遵循 "Don't Repeat Yourself" 的 DRY 原则来重构测试。因为所有测试都通过了,我们就能放心大胆地重构了。只要重构后测试仍然通过,就能确保我们没有破坏任何东西。
# 用工厂函数重构
在几个测试中我们都调用了 shallowMount
并随后传入一个相似的 propsData
对象。我们可以讲这件事重构为一个工厂函数。一个工厂函数只是一个返回单个对象的简单函数 -- 它 制造 对象,这就是其名为 “工厂” 的原因。
const msg = "submit"
const factory = (propsData) => {
return shallowMount(SubmitButton, {
propsData: {
msg,
...propsData
}
})
}
以上就是一个将会 shallowMount
一个 SubmitButton
组件的函数。可以传入任何属性以改变 factory
的首个参数。让我们用这个工厂函数 DRY 测试起来。
describe("SubmitButton", () => {
describe("has admin privileges", ()=> {
it("renders a message", () => {
const wrapper = factory()
expect(wrapper.find("span").text()).toBe("Not Authorized")
expect(wrapper.find("button").text()).toBe("submit")
})
})
describe("does not have admin privileges", ()=> {
it("renders a message", () => {
const wrapper = factory({ isAdmin: true })
expect(wrapper.find("span").text()).toBe("Admin Privileges")
expect(wrapper.find("button").text()).toBe("submit")
})
})
})
再次运行测试。所有事情仍然通过。
PASS tests/unit/SubmitButton.spec.js
SubmitButton
has admin privileges
✓ renders a message (26ms)
does not have admin privileges
✓ renders a message (3ms)
正因为我们有了良好的测试套件,所以就可以容易而放心的重构了。
# 总结
- 通过在加载一个组件时传递
propsData
,就可以设置props
以用于测试 - 工厂函数可以被用来 DRY 你的测试
- 除了
propsData
,你也可以查阅setProps
以在测试中设置属性值