21. Unit Testing(单元测试)

单元测试

安装和工具

与基于模块的构建系统兼容的任何东西都可以工作,但如果您正在寻找特定的建议,请尝试使用Karma测试运行器。它有很多社区插件,包括对WebpackBrowserify的支持。有关详细设置,请参阅每个项目的相应文档。WebpackBrowserify的这些示例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() }) })

我们计划在一组常用测试帮助器上进行工作,以便更容易地呈现具有不同约束的组件(例如,忽略子组件的浅显示)并声明其输出。