由于最近公司沒有什么新的項目贰逾,最近vue3發(fā)布了Beta版悬荣,https://v3.vuejs.org/guide/introduction.html自己也是打算學習一下。不說沖大廠吧疙剑,學習新東西還是挺有趣的践叠。
文末有彩蛋
閑話少說嚼蚀,進入我們今天主題vue的單元測試轿曙!
說到vue的單元測試,我們在用vue-cli創(chuàng)建項目的時候守谓,可以選擇test選項斋荞,而test就是vue-cli詢問我們需要單元測試嗎平酿,如此貼心羡疗,愛了愛了叨恨!
首先說一下,我們使用jest測試的幾個命令小技巧
npm run test:unit button.spec.ts //命令后面跟文件名秉颗,表示單獨執(zhí)行這個測試文件
常用的方法
- .classes() 拿到wrapper所包含的類名,返回一個Array<string>,如果傳入一個類名(不包含.)的時候蚕甥,則返回一個boolearn菇怀。
- .find()傳入一個類名爱沟,返回一個DOMWrapper
- .exists()如果在空的wrapper或wrapperArray上調(diào)用匆背,則返回false钝尸,反之則返回true搂根。
- .toBe()比如傳入的是true剩愧,那么調(diào)用toBe()wrapper必須返回true隙咸,否則會報錯
- .toContain() 是否包含
- .findComponent() 傳入組件的name五督,得到一個VueWrapper
- .text()返回wrapper的內(nèi)容
- emitted() //測試自定義事件的api充包,具體用法看下圖
- toBeFalsy() //當您不關(guān)心一個值是什么遥椿,只希望確保一個值在布爾上下文中為假時使用冠场。在JavaScript中,有6個假值:false钢悲、0莺琳、"惭等、null办铡、undefined和NaN。其他一切都是真實的秤茅。
- toBeTruthy()當您不關(guān)心一個值是什么晒杈,只希望確保一個值在布爾上下文中為真時使用拯钻。在JavaScript中,有6個假值:false拼余、0匙监、"亭姥、null顾稀、undefined和NaN静秆。其他一切都是真實的。
- isVisible()判斷元素是否可見當你有 display: none, visibility: hidden, opacity :0 或者是具有hidden屬性的元素都會返回false
話不多說扶认,進入正題
我們測試的是element源碼中的一個Button組件辐宾,這個組件是我從github上element源碼上拷貝過來的螃概,作為我們此次單元測試的組件
element Button.vue 源碼
<template>
<button
class="el-button"
@click="handleClick"
:disabled="buttonDisabled || loading"
:autofocus="autofocus"
:type="nativeType"
:class="[
type ? 'el-button--' + type : '',
buttonSize ? 'el-button--' + buttonSize : '',
{
'is-disabled': buttonDisabled,
'is-loading': loading,
'is-plain': plain,
'is-round': round,
'is-circle': circle,
},
]"
>
<i class="el-icon-loading" v-if="loading"></i>
<i :class="icon" v-if="icon && !loading"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'ElButton',
inject: {
elForm: {
default: '',
},
elFormItem: {
default: '',
},
},
props: {
type: {
type: String,
default: 'default',
},
size: String,
icon: {
type: String,
default: '',
},
nativeType: {
type: String,
default: 'button',
},
loading: Boolean,
disabled: Boolean,
plain: Boolean,
autofocus: Boolean,
round: Boolean,
circle: Boolean,
},
computed: {
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
buttonSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
buttonDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
},
methods: {
handleClick(evt) {
this.$emit('click', evt);
},
},
};
</script>
測試loading屬性
loading為true,類名為“.el-icon-loading”的這個i元素會被渲染
loading為true制肮,組件會具備“is-loading”這個類名
下面我們看一下怎樣實現(xiàn)這個測試豺鼻?
- .classes() 拿到wrapper所包含的類名,返回一個Array<string>,如果傳入一個類名(不包含.)的時候,則返回一個boolearn谬莹。
- .find()傳入一個類名,返回一個DOMWrapper
- .exists()如果在空的wrapper或wrapperArray上調(diào)用埠戳,則返回false整胃,反之則返回true喳钟。
- .toBe()比如傳入的是true,那么調(diào)用toBe()wrapper必須返回true蛮寂,否則會報錯
import Button from "@/components/element/button.vue";
import { mount } from "@vue/test-utils";
it("loading", () => {
const wrapper = mount(Button, {
props: {
loading:true
}
})
expect(wrapper.classes("is-loading")).toBe(true);//檢查wrapper是否包含這個屬性“is-loading”
expect(wrapper.find('.el-icon-loading').exists()).toBe(true);//檢查類名為“.el-icon-loading”的元素是否為渲染成功
})
測試slot
當我們調(diào)用這個組件共郭,并且設(shè)置slot內(nèi)容的時候疾呻,wrapper的text()是否包含我們設(shè)置的slot內(nèi)容
下面我們看一下怎樣實現(xiàn)這個測試岸蜗?
- .toContain() 是否包含
- .findComponent() 傳入組件的name,得到一個VueWrapper
- .text()返回wrapper的內(nèi)容
it('content', () => {
const camp = {
template: '<div><Button>默認按鈕</Button></div>'
}
const wraper = mount({
template: '<div><Button>默認按鈕</Button></div>'
}, {
global: {
components: { Button }
}
});
expect(wraper.findComponent({ name: 'ElButton' }).text()).toContain('默認按鈕');//檢查文本里面是否包含“默認按鈕”這四個字年缎。
})
測試emit事件
- emitted() //測試自定義事件的api单芜,具體用法看下圖
- toBeFalsy() //當您不關(guān)心一個值是什么洲鸠,只希望確保一個值在布爾上下文中為假時使用馋缅。在JavaScript中,有6個假值:false瘾腰、0覆履、"、null栖雾、undefined和NaN岩灭。其他一切都是真實的赂鲤。
- toBeTruthy()當您不關(guān)心一個值是什么数初,只希望確保一個值在布爾上下文中為真時使用泡孩。在JavaScript中,有6個假值:false仑鸥、0眼俊、"疮胖、null澎灸、undefined和NaN。其他一切都是真實的性昭。
it("設(shè)置loading為true的時候巩梢,要阻止事件發(fā)射", () => {
const wrapper = mount(Button, {
props:
{
loading:true
}
});
wrapper.trigger("click");
expect(wrapper.emitted().click).toBeFalsy();
})
// 設(shè)置elForm.disabled為true的時候阻止事件發(fā)射
it("設(shè)置elForm.disabled為true的時候也要阻止事件發(fā)射", () => {
const wrapper = mount(Button, {
global: {
provide: {
elForm: {
disabled:true
}
}
}
})
wrapper.trigger("click")
expect(wrapper.emitted().click).toBeFalsy()
})
// 正常點擊的時候可以觸發(fā)事件
it("初始點擊按鈕的時候括蝠,可以觸發(fā)emit事件", () => {
const wrapper = mount(Button)
wrapper.trigger("click")
expect(wrapper.emitted().click).toBeTruthy()
})
測試size屬性
上面我們測試了loading忌警、slot秒梳、emit,這三個都是由代表性的箕速,剩下就是普通的size、round這種影響組件樣式的props,我們來隨便寫幾個兴垦,全部的代碼我會放在碼云上面字柠,大家有興趣的話窑业,可以自己拉下來看一下常柄。
// 設(shè)置size,控制按鈕的大小
it('設(shè)置size屬性之后卷玉,按鈕是具有對應(yīng)的類名', () => {
const wrapper = mount(Button, {
props: {
size:"large"
}
})
expect(wrapper.classes("el-button--large")).toBe(true);
})
文末彩蛋:
看完了單元測試揍庄,是不是特別期待vue3的新功能呢蚂子,在下一篇文章缭黔,會給大家把這個button.vue使用vue3的手法重構(gòu)馏谨,是不是特別期待呢惧互,重構(gòu)的時候,我也是遇到了好多坑拨与,很多報錯买喧,到時候會把每個錯誤都詳細記錄一遍,我的文采和文字排版內(nèi)容這倆方面不是特別擅長今缚,但是我會盡力去給大家描述低淡,大家就先湊活的看看蔗蹋,如果有描述不清楚的,私信我,我看到了都會回復(fù)的胁孙,謝謝大家涮较!
克隆地址
https://gitee.com/DayLoveNight/vue3-test.git
下一篇文章,會使用vue3的語法重構(gòu)button組件冈止,和單元測試緊密相連狂票,這里附上文章地址:http://www.reibang.com/p/428c1257d8f8