?
This document uses PHP Chinese website manual Release
我們主要針對(duì)Vuex中的mutaions 和actions進(jìn)行單元測(cè)試。
Mutations 很容易被測(cè)試,因?yàn)樗鼈儍H僅是一些完全依賴參數(shù)的函數(shù)。小技巧是,如果你在 store.js
文件中定義了 mutations,并且使用 ES2015 模塊功能默認(rèn)輸出,那么你仍然可以給 mutations 取個(gè)變量名然后把它輸出去:
const state = { ... } //取個(gè)變量名并輸出mutations export const mutations = { ... } export default new Vuex.Store({ state, mutations })
以下為使用 Mocha + chai 測(cè)試 mutation 的例子(實(shí)際上你可以用任何你喜歡測(cè)試框架)
// mutations.js export const mutations = { increment: state => state.count++ }
// mutations.spec.js import { expect } from 'chai' import { mutations } from './store' // 解構(gòu)賦值mutations(destructure assign mutations) const { increment } = mutations describe('mutations', () => { it('INCREMENT', () => { // mock state const state = { count: 0 } // apply mutation increment(state) // assert result expect(state.count).to.equal(1) }) })
Actions 可能會(huì)更加棘手一些,因?yàn)樗麄兛赡芤笳?qǐng)求外部API.
當(dāng)測(cè)試actions時(shí),我們通常需要增加mocking服務(wù)層——例如,我們可以把API調(diào)用抽象成服務(wù),然后我們?cè)跍y(cè)試中模擬這種服務(wù)。為了便于解決mock的依賴關(guān)系,可以用 Webpack 和 inject-loader 打包測(cè)試文件。
異步action測(cè)試示例:
// actions.js import shop from '../api/shop' export const getAllProducts = ({ dispatch }) => { dispatch('REQUEST_PRODUCTS') shop.getProducts(products => { dispatch('RECEIVE_PRODUCTS', products) }) }
// actions.spec.js // 使用 require 語(yǔ)法處理內(nèi)聯(lián)loaders //inject-loader,返回一個(gè)模塊工廠 //讓我們能夠注入mocked的依賴關(guān)系。 import { expect } from 'chai' const actionsInjector = require('inject!./actions') //使用mocks創(chuàng)建模塊 const actions = actionsInjector({ '../api/shop': { getProducts (cb) { setTimeout(() => { cb([ /* mocked response */ ]) }, 100) } } }) //用指定的mutatios測(cè)試action的輔助函數(shù) const testAction = (action, args, state, expectedMutations, done) => { let count = 0 // mock 提交 const commit = (type, payload) => { const mutation = expectedMutations[count] expect(mutation.type).to.equal(type) if (payload) { expect(mutation.payload).to.deep.equal(payload) } count++ if (count >= expectedMutations.length) { done() } } // 用模擬的 store 和參數(shù)調(diào)用 action action({ commit, state }, ...args) // 檢查是否沒(méi)有 mutation 被 dispatch if (expectedMutations.length === 0) { expect(count).to.equal(0) done() } } describe('actions', () => { it('getAllProducts', done => { testAction(actions.getAllProducts, [], {}, [ { type: 'REQUEST_PRODUCTS' }, { type: 'RECEIVE_PRODUCTS', payload: { /* mocked response */ } } ], done) }) })
如果你的getters方法很復(fù)雜,那么你得測(cè)試他們。測(cè)試Getter 方法和測(cè)試mutations一樣非常簡(jiǎn)單!
測(cè)試getter實(shí)例:
// getters.js export const getters = { filteredProducts (state, { filterCategory }) { return state.products.filter(product => { return product.category === filterCategory }) } }
// getters.spec.js import { expect } from 'chai' import { getters } from './getters' describe('getters', () => { it('filteredProducts', () => { // mock 狀態(tài) const state = { products: [ { id: 1, title: 'Apple', category: 'fruit' }, { id: 2, title: 'Orange', category: 'fruit' }, { id: 3, title: 'Carrot', category: 'vegetable' } ] } // mock getter const filterCategory = 'fruit' // 從getter中取回值 const result = getters.filteredProducts(state, { filterCategory }) // 聲明返回值 expect(result).to.deep.equal([ { id: 1, title: 'Apple', category: 'fruit' }, { id: 2, title: 'Orange', category: 'fruit' } ]) }) })
如果你的 mutations 和 actions 已經(jīng)正確,后面應(yīng)該在適合的mocking上瀏覽器測(cè)試API的依賴關(guān)系。
創(chuàng)建下面的webpack配置(加上適合.babelrc
):
// webpack.config.js module.exports = { entry: './test.js', output: { path: __dirname, filename: 'test-bundle.js' }, module: { loaders: [ { test: /\.js$/, loader: 'babel', exclude: /node_modules/ } ] } }
然后:
webpack mocha test-bundle.js
安裝 mocha-loader
把上述 webpack 配置中的 entry 改成 ‘mocha!babel!./test.js’
用以上配置啟動(dòng) webpack-dev-server
訪問(wèn) localhost:8080/webpack-dev-server/test-bundle
.
詳細(xì)的安裝咨詢見(jiàn)vue-loader documentation.