您好,登錄后才能下訂單哦!
最近領(lǐng)導(dǎo)對前端提出了新的要求,要進(jìn)行單元測試。之前使用vue做了一個(gè)快報(bào)名小程序的pc端頁面,既然要做單元測試,就準(zhǔn)備用這個(gè)項(xiàng)目了,之前有些react的經(jīng)驗(yàn),vue還是第一遭
vue-cli3.0單元測試方面更加完備,就先升級(jí)到了cli3.0,因?yàn)轫?xiàng)目是用typescript寫的,需要ts-jest,得到j(luò)est的配置如下
{ "jest": { "moduleFileExtensions": [ "js", "jsx", "json", "vue", "ts", "tsx" ], "transform": { "^.+\\.vue$": "vue-jest", ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub", "^.+\\.tsx?$": "ts-jest" }, "moduleNameMapper": { "^@/(.*)$": "<rootDir>/src/$1" }, "snapshotSerializers": [ "jest-serializer-vue" ], "testMatch": [ "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" ], "testURL": "http://localhost/" } }
先從簡單的開始,測試了一個(gè)正則字符串常量文件,完美,一點(diǎn)問題沒有
然后開始測方案頁面的Scheme.vue組件,這個(gè)地方主要就想測一個(gè)computed屬性,將三種有代表性的情況寫完測試案例,興沖沖運(yùn)行yarn test:unit Scheme.test.ts,結(jié)果還不錯(cuò),三個(gè)it測試用例都通過了,但后面還有一片紅是什么鬼
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Invalid prop: type check failed for prop "headerPic". Expected String, got Object.
原來是這個(gè)地方調(diào)用了一個(gè)組件,這個(gè)組件需要一個(gè)headerPic
屬性,用作圖片的src,看源碼
<SideNav :header-pic="require('../../assets/scheme/schemeSideNavPic.jpg')">
感覺沒毛病啊,去vue-devtool,"/img/schemeSideNavPic.f988623b.jpg"
是字符串啊,一點(diǎn)毛病沒有,應(yīng)該不是require的問題啊,應(yīng)該是require在jest里面的處理問題,再查看jest配置,已經(jīng)對jpg
等靜態(tài)文件做處理了,看了一下jest-transform-stub模塊的源碼,很簡單
module.exports = { process: function() { return '' } }
既對這些靜態(tài)文件返回空字符串,不做處理,這不就更不應(yīng)該了呀,幸虧有vscode這款利器,可以方便調(diào)試源碼,使用vscode調(diào)試沒有報(bào)錯(cuò),也沒能讓調(diào)試器進(jìn)入vue文件,沒辦法,在ts文件里const pic = require('../../../assets/scheme/schemeSideNavPic.jpg')
,再次調(diào)試,發(fā)現(xiàn)
正是jest-transform-stub的內(nèi)容,確實(shí)是個(gè)對象,跟在命令行內(nèi)運(yùn)行結(jié)果一致,也就是說只需要一直處理方式讓其返回為
module.exports = ""
查看jest官網(wǎng),搜了一下css,運(yùn)氣不錯(cuò)😂, 處理靜態(tài)文件,moduleNameMapper
選項(xiàng)完全可以滿足需求啊,
"moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js" }
fileMock.js內(nèi)容
// __mocks__/fileMock.js module.exports = 'test-file-stub';
就是說只要返回字符串就OK了,加上moduleNameMapper
,測試完美的跑通了
接下來對Scheme.vue組件發(fā)起模擬點(diǎn)擊測試
const createScheme = wrapper.findAll('.sn-item').at(1) createScheme.trigger('click') expect((wrapper.vm as any).isCreateDialogShow).toBeTruthy() expect(wrapper.find('.create-list-dialog').isVisible()).toBeTruthy()
使用vue-test-utils的api獲取createScheme元素,對其觸發(fā)點(diǎn)擊,測試isCreateDialogShow這個(gè)data值被設(shè)置成true, 使用的element-ui
<el-dialog :visible.sync="isCreateDialogShow" width="600px" class="create-list-dialog" title="創(chuàng)建方案"> ... </el-dialog>
此dialog可見,順利通過
接下來再實(shí)驗(yàn)一下新功能,快照,使用toMatchSnapshot
方法也順利通過了
接下來來個(gè)大的,測試一下Login.vue,登陸頁面,主要測其調(diào)接口,然后成功設(shè)置store值,但不能走真實(shí)的網(wǎng)絡(luò)接口啊,這太慢不說,具體結(jié)果還不能預(yù)測,得使用mock數(shù)據(jù)
在項(xiàng)目中創(chuàng)建了axios.plugin.ts
vue插件,這可怎么mock呀,再看官方文檔,感覺Manual Mocks部分最合適,但是舉例也不適合vue 插件mock啊,繼續(xù)瀏覽網(wǎng)站,不知道是受哪的啟發(fā)還是突然開竅了,應(yīng)該是受fs
模塊啟發(fā),突然知道怎么mock插件了,mock一個(gè)模塊只需要模仿其型即可,具體實(shí)現(xiàn),就無所謂了,這個(gè)http請求插件的mock必須能返回我們期望的值啊,fs
模塊的__setMockFiles
又給了我啟示,可以直接給接口的返回result設(shè)值啊,然后就有來下面的
__mocks__/axios.plugin.ts
文件
const MockAxios = {} as any let result = {} as any MockAxios.install = (Vue: any, options: any) => { Vue.prototype.$axios = function () { /* eslint-disable prefer-promise-reject-errors */ return new Promise((resolve, reject) => { if (result.ResultCode === '200') { return result.Info } else { reject({ code: result.ResultCode, msg: result.Message, info: result.Info }) } }) } } MockAxios.__setMockData = (data: any) => { result = data } export default MockAxios
然后一馬平川了,localVue.use(Vuex)
, localVue.use(AxiosPlugin)
const mockData = { ResultCode: '200', Msg: true, Info: { OpenId: 99, UserId: 92003, }, } AxiosPlugin.__setMockData(mockData) (wrapper.vm as any).login({ code: '29992' }).then(() => { expect(wrapper.vm.$store.state.userInfo.OpenId).toBe(mockData.Info.OpenId) expect(wrapper.vm.$store.state.userInfo.UserId).toBe(mockData.Info.UserId) })
完美通過,vue的單元測試框架算是基本搭好了,也能給領(lǐng)導(dǎo)說說了
給領(lǐng)導(dǎo)看還得有個(gè)覆蓋率報(bào)告
yarn test:unit --coverage
覆蓋的文件比較少啊,不包含所有的源文件啊,需要加入collectCoverageFrom
配置項(xiàng),至此整個(gè)單元測試就比較完備了
下面是完整jest的配置
{ "jest": { "moduleFileExtensions": [ "js", "jsx", "json", "vue", "ts", "tsx" ], "transform": { "^.+\\.vue$": "vue-jest", ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub", "^.+\\.tsx?$": "ts-jest" }, "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", "^@/(.*)$": "<rootDir>/src/$1" }, "snapshotSerializers": [ "jest-serializer-vue" ], "testMatch": [ "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" ], "testURL": "http://localhost/", "collectCoverageFrom": [ "**/*.{vue,ts}", "!**/node_modules/**", "!**/*.d.ts" ] } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。