單元測(cè)試第四彈——使用Mock技術(shù)進(jìn)行單元測(cè)試
碰撞測(cè)試是汽車開(kāi)發(fā)活動(dòng)中的重要組成部分。所有汽車在上市之前都要經(jīng)過(guò)碰撞測(cè)試,并公布測(cè)試結(jié)果。碰撞測(cè)試的目的用于評(píng)定運(yùn)輸包裝件在運(yùn)輸過(guò)程中承受多次重復(fù)性機(jī)械碰撞的耐沖擊強(qiáng)度及包裝對(duì)內(nèi)裝物的保護(hù)能力。說(shuō)簡(jiǎn)單點(diǎn)就是為了測(cè)試汽車在碰撞的時(shí)候鎖所產(chǎn)生的自身?yè)p傷、對(duì)車內(nèi)人員及車外人員、物品等的損傷情況。
在進(jìn)行汽車的碰撞測(cè)試時(shí),當(dāng)然不能讓真人來(lái)進(jìn)行測(cè)試,一般采用假人來(lái)測(cè)試。但是為了保證測(cè)試的真實(shí)性及可靠性,假人的生物力學(xué)性能應(yīng)該和人體一樣——比如身體各部分的大小和質(zhì)量,以及關(guān)節(jié)的剛性等等,只有這樣使用它們的模擬才能和現(xiàn)實(shí)相匹配。為了保證覆蓋到的情況夠全面,一般都會(huì)使用各種不同的假人,不同的假人模擬男性或者女性的身體,以及不同身高和年齡的人體。
想想軟件測(cè)試,其實(shí)和汽車的碰撞測(cè)試流程差不多。一個(gè)軟件在發(fā)布上線之前都要經(jīng)過(guò)各種測(cè)試,并產(chǎn)出測(cè)試報(bào)告,更嚴(yán)格的一點(diǎn)的要保證單測(cè)覆蓋率不能低于某個(gè)值。和汽車碰撞測(cè)試類似,我們?cè)谲浖y(cè)試中也會(huì)用到很多“假人”。用這些“假人”的目的也是為了保證測(cè)試有效的進(jìn)行。
why
不知道你在日常開(kāi)發(fā)中有沒(méi)有遇到過(guò)以下問(wèn)題或需求:
1、和別人一起做同一個(gè)項(xiàng)目,相互之間已經(jīng)約定好接口。然后你開(kāi)始開(kāi)發(fā),開(kāi)發(fā)完自己的代碼后,你想測(cè)試下你的服務(wù)實(shí)現(xiàn)邏輯是否正確。但是因?yàn)槟阋蕾嚨闹皇墙涌?,真正的服?wù)還有開(kāi)發(fā)出來(lái)。
2、還是和上面類似的場(chǎng)景,你要依賴的服務(wù)是通過(guò)RPC的方式調(diào)用的,而外部服務(wù)的穩(wěn)定性很難保證。
3、對(duì)于一個(gè)接口或者方法,你希望測(cè)試其各種不同情況,但是依賴的服務(wù)的執(zhí)行策略及返回值你沒(méi)辦法決定。
4、你依賴的服務(wù)或者對(duì)象很難創(chuàng)建!(比如具體的web容器)
5、依賴的對(duì)象的某些行為很難觸發(fā)!(比如網(wǎng)絡(luò)異常)
6、以上問(wèn)題你都沒(méi)有,但是你要用的那個(gè)服務(wù)他處理速度實(shí)在是太慢了。
上面這些情況都是日常開(kāi)發(fā)測(cè)試過(guò)程中可能遇到的比較麻煩的問(wèn)題。這些問(wèn)題都會(huì)大大的提高測(cè)試成本??梢哉f(shuō),很多開(kāi)發(fā)人員不愿意寫單元測(cè)試很大程度上都和以上這六點(diǎn)有關(guān)系。
幸運(yùn)的是,Mock對(duì)象可以解決以上問(wèn)題。使用mock對(duì)象進(jìn)行的測(cè)試就是mock測(cè)試。
what
mock測(cè)試就是在測(cè)試過(guò)程中,對(duì)于某些不容易構(gòu)造或者不容易獲取的對(duì)象,用一個(gè)虛擬的對(duì)象來(lái)創(chuàng)建以便測(cè)試的測(cè)試方法。
mock對(duì)象,就是非真實(shí)對(duì)象,是模擬出來(lái)的一個(gè)對(duì)象??梢岳斫鉃槠嚺鲎矞y(cè)試的那個(gè)假人。mock對(duì)象就是真實(shí)對(duì)象在調(diào)試期間的代替品。
你創(chuàng)建這樣一個(gè)“假人”的成本比較低,這個(gè)“假人”可以按照你設(shè)定的“劇情”來(lái)運(yùn)行。
在Java的單元測(cè)試中,很多Mock框架可以使用,用的比較多的有easymock、mockito、powermock、jmockit等。
面向?qū)ο箝_(kāi)發(fā)中,我們通常定義一個(gè)接口,使用一個(gè)接口來(lái)描述這個(gè)對(duì)象。在被測(cè)試代碼中只是通過(guò)接口來(lái)引用對(duì)象,所以它不知道這個(gè)引用的對(duì)象是真實(shí)對(duì)象,還是mock對(duì)象。
好了,這篇文章的內(nèi)容差不多就這些了,主要是讓大家知道,在Java中可以使用mock對(duì)象來(lái)模擬真實(shí)對(duì)象來(lái)進(jìn)行單元測(cè)試,好處很多。下一篇會(huì)詳細(xì)介紹如何使用mockito框架進(jìn)行單元測(cè)試。
【本文是51CTO專欄作者Hollis的原創(chuàng)文章,作者微信公眾號(hào)Hollis(ID:hollischuang)】