在Vue項目
中測試組件時會引用全局組件,那麼如何處理這些全局組件呢? 還有Vue
中比較重要的一個點就是Vuex
如何進行測試?javascript
在你的組件中引用了全局組件 router-link
或者 router-view
組件時,咱們使用shallowMount
來渲染時會提示沒法找到這兩個組件,咱們能夠使用存根的方式mock
掉相關的組件。前端
<template>
<div>
<h1>當前路由:{{this.$route.path}}</h1>
<router-link to="/">首頁</router-link>
<router-link to="/about">關於頁面</router-link>
<router-view></router-view>
</div>
</template>
複製代碼
import Nav from "@/components/Nav.vue";
import { shallowMount } from "@vue/test-utils";
it("測試Nav組件", () => {
let wrapper = shallowMount(Nav,{
// 忽略這兩個組件
stubs:['router-link','router-view'],
mocks:{ // mock一些數據傳入到Nav組件中
$route:{path:'/'}
}
});
expect(wrapper.find('h1').text()).toContain('/')
});
複製代碼
同理:咱們能夠
mock
掉一些全局組件,也能夠mock
一些參數傳入到組件中。vue
咱們能夠也建立一個localVue
來安裝VueRouter,傳入到組件中進行渲染。java
安裝 Vue Router
以後 Vue 的原型上會增長 $route
和 $router
這兩個只讀屬性。因此不要掛載到基本的Vue構造函數上,同時也不能經過mocks
參數重寫這兩個屬性vuex
const localVue = createLocalVue();
localVue.use(VueRouter);
it("測試Nav組件", () => {
let router = new VueRouter({
routes:[
{path:'/',component:Home},
{path:'/about',component:About}
]
});
let wrapper = mount(Nav,{
localVue,
router
});
router.push('/about');
expect(wrapper.find('h1').text()).toMatch(/about/)
});
複製代碼
咱們經過一個計數器
的例子來掌握如何測試vuex。app
<template>
<div>
{{this.$store.state.number}}
<button @click="add(3)">添加</button>
</div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
methods:{
...mapActions({'add':'increment'})
}
}
</script>
複製代碼
編寫store/index.js
異步
import Vue from 'vue'
import Vuex from 'vuex'
import config from './config'
Vue.use(Vuex)
export default new Vuex.Store(config)
複製代碼
編寫store/mutations.js
函數
export default {
increment(state,count){
state.number+=count
}
}
複製代碼
編寫store/actions.js
post
export default {
increment({ commit }, count) {
setTimeout(() => {
commit("increment", count);
}, 1000);
}
};
複製代碼
編寫store/config.js
單元測試
import mutations from "./mutations";
import actions from "./actions";
export default {
state: {
number: 0
},
mutations,
actions
};
複製代碼
這裏咱們就不過多詳細講解vuex的執行過程了,直接開始測試啦!
咱們能夠直接把store
中的方法一一進行單元測試。
就是逐個測試函數,可是須要用mock來 commit
和dispatch
方法。
import mutations from '../mutations';
import actions from '../actions';
jest.useFakeTimers();
it('測試mutation',()=>{
const state = {number:0};
mutations.increment(state,2);
expect(state.number).toBe(2);
});
it('測試action',()=>{
let commit = jest.fn();
actions.increment({commit},2);
jest.advanceTimersByTime(2000);
expect(commit).toBeCalled();
expect(commit.mock.calls[0][1]).toBe(2);
});
複製代碼
就是產生一個store
進行測試,好處是不須要mock
任何方法。
import Vuex from 'vuex';
import {createLocalVue} from '@vue/test-utils'
import config from '../config';
jest.useFakeTimers();
it('測試是否能夠異步增長 1',()=>{
let localVue = createLocalVue();
localVue.use(Vuex);
let store = new Vuex.Store(config); // 建立一個運行store
expect(store.state.number).toBe(0);
store.dispatch('increment',2);
jest.advanceTimersByTime(2000); // 前進2s
expect(store.state.number).toBe(2);
});
複製代碼
config文件最好每次測試時克隆一份,保證每一個用例間互不干擾!
mock store
傳入組件中,看函數是否可以如期調用。
import Vuex from 'vuex';
import Counter from '@/components/Counter';
import {createLocalVue,shallowMount} from '@vue/test-utils'
let localVue = createLocalVue();
localVue.use(Vuex);
let store;
let actions;
beforeEach(()=>{
actions = {
increment:jest.fn()
}
store = new Vuex.Store({
actions,
state:{}
});
});
it('測試組件中點擊按鈕 是否能夠 1',()=>{
let wrapper = shallowMount(Counter,{
localVue,
store
});
wrapper.find('button').trigger('click');
// 測試actions中的increment 方法是否能正常調用
expect(actions.increment).toBeCalled();
})
複製代碼
到這裏
Vuex
測試的方式咱們就講解完畢了,其實前端自動化測試並無想象中的難,你們多多練習就能夠徹底掌握啦!
往期文章:
但願你們能夠關注公衆號【前端優選】,有任何想法和意見歡迎討論交流!連續四天的連載到這裏先要告一段落了,祝你們中秋節快樂!