11# 测试
22
3- Mutations 很容易测试,因为它仅仅是一个完全依赖参数的函数。相比之下,测试 Actions 会复杂一些,因为 actions 可能会调用一些外部的 API。 测试 actions 的时候我们需要做一定的 mocking —— 比如说把 API 调用抽象成一个 service,然后测试的时候用另一个 mock 的 service. 为了方便地 mock,我们可以使用 Webpack 和 [ inject-loader ] ( https://github.com/plasticine/inject-loader ) 来打包测试文件 。
3+ 我们主要想针对 Vuex 中的 mutaions 和 actions 进行单元测试 。
44
5- 如果你的 mutation 和 action 遵循了 Vuex 的规则,那么在 mock 之后它们应该对浏览器 API 没有任何直接依赖。因此,打包之后的文件可以直接在 Node.js 下运行。如果你想要在真正的浏览器里跑测试,则可以使用 ` mocha-loader ` 或是 Karma + ` karma-webpack ` 的组合。
5+ ## 测试 Mutations
66
7- 下面是用 Mocha + Chai 测试一个 mutation 的例子(实际上你可以用任何你喜欢的测试框架) :
7+ Mutations 很容易被测试,因为它们仅仅是一些完全依赖参数的函数。这里有一个小技巧,如果你在 ` store.js ` 文件中定义了 mutations,并且使用 ES2015 模块功能默认输出了 Vuex.Store 的实例,那么你仍然可以给 mutation 取个变量名然后把它输出去 :
88
99``` js
10- // mutations.js
11- export const INCREMENT = state => state .count ++
10+ const state = { ... }
11+
12+ // mutations 作为命名输出对象
13+ export const mutations = { ... }
14+
15+ export default new Vuex .Store ({
16+ state,
17+ mutations
18+ })
1219```
1320
21+ 下面是用 Mocha + Chai 测试一个 mutation 的例子(实际上你可以用任何你喜欢的测试框架):
22+
1423``` js
1524// mutations.spec.js
1625import { expect } from ' chai'
17- import { INCREMENT } from ' ./mutations'
26+ import { mutations } from ' ./store'
27+
28+ // 解构 mutations
29+ const { INCREMENT } = mutations
1830
1931describe (' mutations' , () => {
2032 it (' INCREMENT' , () => {
21- // mock state
33+ // 模拟状态
2234 const state = { count: 0 }
23- // apply mutation
35+ // 应用 mutation
2436 INCREMENT (state)
25- // assert result
37+ // 断言结果
2638 expect (state .count ).to .equal (1 )
2739 })
2840})
2941```
3042
31- 测试异步 action 的例子:
43+ ## 测试 Actions
44+
45+ Actions 应对起来略微棘手,因为它们可能需要调用外部的 API。当测试 actions 的时候,我们需要增加一个 mocking 服务层 —— 例如,我们可以把 API 调用抽象成服务,然后在测试文件中用 mock 服务回应 API 调用。为了便于解决 mock 依赖,可以用 Webpack 和 [ inject-loader] ( https://github.com/plasticine/inject-loader ) 打包测试文件。
46+
47+ 下面是一个测试异步 action 的例子:
3248
3349``` js
3450// actions.js
@@ -44,13 +60,13 @@ export const getAllProducts = ({ dispatch }) => {
4460
4561``` js
4662// actions.spec.js
63+
64+ // 使用 require 语法处理内联 loaders。
65+ // inject-loader 返回一个允许我们注入 mock 依赖的模块工厂
4766import { expect } from ' chai'
48- // 这里因为需要用 webpack loader 所以使用 require() 而不是 import
49- // inject-loader 会返回一个工厂函数。这个工厂函数让我们可以对该模块的
50- // 依赖进行 mock
5167const actionsInjector = require (' inject!./actions' )
5268
53- // 调用工厂函数,获得 mock 过依赖的 actions 模块
69+ // 使用 mocks 创建模块
5470const actions = actionsInjector ({
5571 ' ../api/shop' : {
5672 getProducts (cb ) {
@@ -61,11 +77,11 @@ const actions = actionsInjector({
6177 }
6278})
6379
64- // 这是一个可复用的助手函数,用于断言一个 action 应触发的 mutations
65- const testAction = (action , state , expectedMutations , done ) => {
80+ // 用指定的 mutaions 测试 action 的辅助函数
81+ const testAction = (action , args , state , expectedMutations , done ) => {
6682 let count = 0
67- // mock dispatch
68- const dispatch = (name , payload ) => {
83+ // 模拟 dispatch
84+ const dispatch = (name , ... payload ) => {
6985 const mutation = expectedMutations[count]
7086 expect (mutation .name ).to .equal (name)
7187 if (payload) {
@@ -76,25 +92,31 @@ const testAction = (action, state, expectedMutations, done) => {
7692 done ()
7793 }
7894 }
79- // call the action with mocked store
80- action ({
81- dispatch,
82- state
83- })
95+ // 用模拟的 store 和参数调用 action
96+ action ({dispatch, state}, ... args)
97+
98+ // 检查是否没有 mutation 被 dispatch
99+ if (count === 0 ) {
100+ expect (expectedMutations .length ).to .equal (0 )
101+ done ()
102+ }
84103}
85104
86- // 实际测试
87105describe (' actions' , () => {
88106 it (' getAllProducts' , done => {
89- testAction (actions .getAllProducts , {}, [
107+ testAction (actions .getAllProducts , [], {}, [
90108 { name: ' REQUEST_PRODUCTS' },
91109 { name: ' RECEIVE_PRODUCTS' , payload: [ /* mocked response */ ] }
92110 ], done)
93111 })
94112})
95113```
96114
97- ### 在 Node 中运行
115+ ### 执行测试
116+
117+ 如果你的 mutations 和 actions 编写正确,经过合理地 mocking 处理之后这些测试应该不依赖任何浏览器 API,因此你可以直接用 Webpack 打包这些测试文件然后在 Node 中执行。换种方式,你也可以用 ` mocha-loader ` 或 ` Karma ` + ` karma-webpack ` 在真实浏览器环境中进行测试。
118+
119+ #### 在 Node 中执行测试
98120
99121创建以下 webpack 配置:
100122
@@ -127,9 +149,13 @@ webpack
127149mocha test-bundle.js
128150```
129151
130- ### 在浏览器中运行
152+ ### 在浏览器中执行测试
131153
1321541 . 安装 ` mocha-loader `
133- 2 . webpack 配置中的 entry 改成 ` 'mocha!babel!./test.js' `
155+ 2 . 把上述 webpack 配置中的 ` entry ` 改成 ` 'mocha!babel!./test.js' `
1341563 . 用以上配置启动 ` webpack-dev-server `
135- 4 . 打开 ` localhost:8080/webpack-dev-server/test-bundle ` .
157+ 4 . 访问 ` localhost:8080/webpack-dev-server/test-bundle ` .
158+
159+ #### 使用 Karma + karma-webpack 在浏览器中执行测试
160+
161+ 详询 [ vue-loader documentation] ( http://vuejs.github.io/vue-loader/workflow/testing.html ) 。
0 commit comments