針對 Vuex 的 Getter 做 Unit Test

Vuex 分成 State、Mutation、Getter 與 Action 四部分,由於都是圍繞在 Data,因此都是針對 Data 做測試。

本文討論 Getter 的 Unit Test。

Version


Vue 2.5.22
Vuex 3.0.1
Vue-test-utils 1.0.0-beta.20

Store


books-info.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { fetchBooks } from '@/api/books';

/** mutation */
const setBooks = (state, { books }) => state.books = books;

/** action */
const saveBooks = commit => ({ data }) => commit('setBooks', data);
const loadBooks = ({ commit }) => fetchBooks().then(saveBooks(commit));

/** getter */
const booksCount = ({ books }) => books.length;

export default {
namespaced: true,
state: {
books: []
},
mutations: {
setBooks
},
getters: {
booksCount
},
actions: {
loadBooks
},
};

一個典型的 Vuex store,包含 statemutationsgettersactions

10 行

1
2
/** getter */
const booksCount = ({ books }) => books.length;

booksCount() 為典型的 getter,將 books state 的 length property 傳回。

Unit Test


getter.spec.js

1
2
3
4
5
6
7
8
9
10
11
12
13
import store from '@/store/modules/books-info';

test('booksCount() getter', () => {
/** arrange */
const stub = [1, 2, 3];
const state = { books: stub };

/** act */
const result = store.getters.booksCount(state);

/** assert */
expect(result).toBe(3);
});

第 1 行

1
import store from '@/store/modules/books-info';

將要測試的 store import 進來。

第 3 行

1
2
3
4
5
6
7
test('booksCount() getter', () => {
/** arrange */

/** act */

/** assert */
});

所有的 unit test 都包在 test() 的第二個參數,以 Arrow Function 表示。

test() 的第一個參數為 description,可描述 test case。

一樣使用 3A 原則寫 unit test。

第 4 行

1
2
3
/** arrange */
const stub = [1, 2, 3];
const state = { books: stub };

要測試 getter,有兩個原則:

  1. 提供 stub 並透過 fake state object 寫入 books state 的初始值
  2. 執行 getter,並驗證 getter 結果是否等於 stub 所預期的結果
1
const stub = [1, 2, 3];

建立要測試的 stub。

1
const state = { books: stub };

建立 fake state object,並以 stub 建立 state 的初始值。

第 8 行

1
2
/** act */
const result = store.getters.booksCount(state);

實際執行 booksCount() getter,並傳入剛在 arrange 建立的 fake state。

bookCount() getter 結果存於 result

11 行

1
2
/** assert */
expect(result).toBe(3);

驗證 result 是否等於預期結果。

1
$ yarn test:unit

getter000

通過 unit test 得到 綠燈

Conclusion


  • Vuex 的 Getter 本質是 function,且職責很確定,因此 unit test 非常好寫
  • 由於 getter 的職責只有讀取 state,測試手法就是提供 stub 並透過 fake state object 建立 state 初始值,然後執行 getter 並驗證結果是否如預期

Sample Code


完整範例可以在我的 GitHub 上找到