1
1
# 测试
2
2
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 进行单元测试 。
4
4
5
- 如果你的 mutation 和 action 遵循了 Vuex 的规则,那么在 mock 之后它们应该对浏览器 API 没有任何直接依赖。因此,打包之后的文件可以直接在 Node.js 下运行。如果你想要在真正的浏览器里跑测试,则可以使用 ` mocha-loader ` 或是 Karma + ` karma-webpack ` 的组合。
5
+ ## 测试 Mutations
6
6
7
- 下面是用 Mocha + Chai 测试一个 mutation 的例子(实际上你可以用任何你喜欢的测试框架) :
7
+ Mutations 很容易被测试,因为它们仅仅是一些完全依赖参数的函数。这里有一个小技巧,如果你在 ` store.js ` 文件中定义了 mutations,并且使用 ES2015 模块功能默认输出了 Vuex.Store 的实例,那么你仍然可以给 mutation 取个变量名然后把它输出去 :
8
8
9
9
``` 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
+ })
12
19
```
13
20
21
+ 下面是用 Mocha + Chai 测试一个 mutation 的例子(实际上你可以用任何你喜欢的测试框架):
22
+
14
23
``` js
15
24
// mutations.spec.js
16
25
import { expect } from ' chai'
17
- import { INCREMENT } from ' ./mutations'
26
+ import { mutations } from ' ./store'
27
+
28
+ // 解构 mutations
29
+ const { INCREMENT } = mutations
18
30
19
31
describe (' mutations' , () => {
20
32
it (' INCREMENT' , () => {
21
- // mock state
33
+ // 模拟状态
22
34
const state = { count: 0 }
23
- // apply mutation
35
+ // 应用 mutation
24
36
INCREMENT (state)
25
- // assert result
37
+ // 断言结果
26
38
expect (state .count ).to .equal (1 )
27
39
})
28
40
})
29
41
```
30
42
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 的例子:
32
48
33
49
``` js
34
50
// actions.js
@@ -44,13 +60,13 @@ export const getAllProducts = ({ dispatch }) => {
44
60
45
61
``` js
46
62
// actions.spec.js
63
+
64
+ // 使用 require 语法处理内联 loaders。
65
+ // inject-loader 返回一个允许我们注入 mock 依赖的模块工厂
47
66
import { expect } from ' chai'
48
- // 这里因为需要用 webpack loader 所以使用 require() 而不是 import
49
- // inject-loader 会返回一个工厂函数。这个工厂函数让我们可以对该模块的
50
- // 依赖进行 mock
51
67
const actionsInjector = require (' inject!./actions' )
52
68
53
- // 调用工厂函数,获得 mock 过依赖的 actions 模块
69
+ // 使用 mocks 创建模块
54
70
const actions = actionsInjector ({
55
71
' ../api/shop' : {
56
72
getProducts (cb ) {
@@ -61,11 +77,11 @@ const actions = actionsInjector({
61
77
}
62
78
})
63
79
64
- // 这是一个可复用的助手函数,用于断言一个 action 应触发的 mutations
65
- const testAction = (action , state , expectedMutations , done ) => {
80
+ // 用指定的 mutaions 测试 action 的辅助函数
81
+ const testAction = (action , args , state , expectedMutations , done ) => {
66
82
let count = 0
67
- // mock dispatch
68
- const dispatch = (name , payload ) => {
83
+ // 模拟 dispatch
84
+ const dispatch = (name , ... payload ) => {
69
85
const mutation = expectedMutations[count]
70
86
expect (mutation .name ).to .equal (name)
71
87
if (payload) {
@@ -76,25 +92,31 @@ const testAction = (action, state, expectedMutations, done) => {
76
92
done ()
77
93
}
78
94
}
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
+ }
84
103
}
85
104
86
- // 实际测试
87
105
describe (' actions' , () => {
88
106
it (' getAllProducts' , done => {
89
- testAction (actions .getAllProducts , {}, [
107
+ testAction (actions .getAllProducts , [], {}, [
90
108
{ name: ' REQUEST_PRODUCTS' },
91
109
{ name: ' RECEIVE_PRODUCTS' , payload: [ /* mocked response */ ] }
92
110
], done)
93
111
})
94
112
})
95
113
```
96
114
97
- ### 在 Node 中运行
115
+ ### 执行测试
116
+
117
+ 如果你的 mutations 和 actions 编写正确,经过合理地 mocking 处理之后这些测试应该不依赖任何浏览器 API,因此你可以直接用 Webpack 打包这些测试文件然后在 Node 中执行。换种方式,你也可以用 ` mocha-loader ` 或 ` Karma ` + ` karma-webpack ` 在真实浏览器环境中进行测试。
118
+
119
+ #### 在 Node 中执行测试
98
120
99
121
创建以下 webpack 配置:
100
122
@@ -127,9 +149,13 @@ webpack
127
149
mocha test-bundle.js
128
150
```
129
151
130
- ### 在浏览器中运行
152
+ ### 在浏览器中执行测试
131
153
132
154
1 . 安装 ` mocha-loader `
133
- 2 . webpack 配置中的 entry 改成 ` 'mocha!babel!./test.js' `
155
+ 2 . 把上述 webpack 配置中的 ` entry ` 改成 ` 'mocha!babel!./test.js' `
134
156
3 . 用以上配置启动 ` 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