21. Unit Testing(单元测试)
单元测试
安装和工具
与基于模块的构建系统兼容的任何东西都可以工作,但如果您正在寻找特定的建议,请尝试使用Karma测试运行器。它有很多社区插件,包括对Webpack和Browserify的支持。有关详细设置,请参阅每个项目的相应文档。Webpack和Browserify的这些示例Karma配置可以帮助您开始。
简单的断言
您无需为组件做任何特殊的操作即可进行测试。导出原始选项:
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
然后将组件选项与Vue一起导入,并且可以创建许多常见断言:
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
// Here are some Jasmine 2.0 tests, though you can
// use any test runner / assertion library combo you prefer
describe('MyComponent', () => {
// Inspect the raw component options
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
// Evaluate the results of functions in
// the raw component options
it('sets the correct default data', () => {
expect(typeof MyComponent.data).toBe('function')
const defaultData = MyComponent.data()
expect(defaultData.message).toBe('hello!')
})
// Inspect the component instance on mount
it('correctly sets the message when created', () => {
const vm = new Vue(MyComponent).$mount()
expect(vm.message).toBe('bye!')
})
// Mount an instance and inspect the render output
it('renders the correct message', () => {
const Ctor = Vue.extend(MyComponent)
const vm = new Ctor().$mount()
expect(vm.$el.textContent).toBe('bye!')
})
})
编写可测试组件
组件的渲染输出主要取决于它们收到的props。如果一个组件的渲染输出完全依赖于它的props,那么测试变得很直接,类似于用不同参数来断言纯函数的返回值。举一个简单的例子:
<template>
<p>{{ msg }}</p>
</template>
<script>
export default {
props: ['msg']
}
</script>
您可以使用以下propsData
选项使用不同的props来声明其渲染输出:
import Vue from 'vue'
import MyComponent from './MyComponent.vue'
// helper function that mounts and returns the rendered text
function getRenderedText (Component, propsData) {
const Ctor = Vue.extend(Component)
const vm = new Ctor{ propsData: propsData }).$mount()
return vm.$el.textContent
}
describe('MyComponent', () => {
it('renders correctly with different props', () => {
expect(getRenderedText(MyComponent, {
msg: 'Hello'
})).toBe('Hello')
expect(getRenderedText(MyComponent, {
msg: 'Bye'
})).toBe('Bye')
})
})
声明异步更新
由于Vue异步执行DOM更新,因此状态更改导致的DOM更新断言必须在Vue.nextTick
回调中进行:
// Inspect the generated HTML after a state update
it('updates the rendered message when vm.message updates', done => {
const vm = new Vue(MyComponent).$mount()
vm.message = 'foo'
// wait a "tick" after state change before asserting DOM updates
Vue.nextTick(() => {
expect(vm.$el.textContent).toBe('foo')
done()
})
})
我们计划在一组常用测试帮助器上进行工作,以便更容易地呈现具有不同约束的组件(例如,忽略子组件的浅显示)并声明其输出。