單元測(cè)試-如何去mock對(duì)象
Python實(shí)戰(zhàn)社群
Java實(shí)戰(zhàn)社群
長(zhǎng)按識(shí)別下方二維碼,按需求添加
掃碼關(guān)注添加客服
進(jìn)Python社群▲
掃碼關(guān)注添加客服
進(jìn)Java社群▲
作者丨Coder技術(shù)棧
來(lái)源丨匠心Java
概念
Mock的概念,其實(shí)很簡(jiǎn)單:所謂的mock就是創(chuàng)建一個(gè)類的虛假的對(duì)象,在測(cè)試環(huán)境中,用來(lái)替換掉真實(shí)的對(duì)象,以達(dá)到兩大目的:
驗(yàn)證這個(gè)對(duì)象的某些方法的調(diào)用情況,調(diào)用了多少次,參數(shù)是什么等等
指定這個(gè)對(duì)象的某些方法的行為,返回特定的值,或者是執(zhí)行特定的動(dòng)作
上述兩大目的應(yīng)該好好理解一下,理解了目的也就大致知道了何時(shí)使用mock
使用場(chǎng)景
被測(cè)試對(duì)象依賴的對(duì)象構(gòu)造復(fù)雜
比如:class A 依賴 class B、class B 依賴 class C和class D、class C 依賴 ...、class D 依賴 ... 此處我們想測(cè)試classA,在沒(méi)有mock的情況下就要去根據(jù)要求去構(gòu)造classBCD等對(duì)象,耗時(shí)耗力。在mock的情況下,我們可以直接mockclassBCD并通過(guò)設(shè)計(jì)其行為來(lái)實(shí)現(xiàn)測(cè)試classA的目的,因?yàn)槲覀冎皇窍霚y(cè)試class A的行為是否符合預(yù)期,我們并不需要測(cè)試依賴對(duì)象。
被測(cè)試單元所依賴的模塊還沒(méi)有開(kāi)發(fā)完成,而被測(cè)試對(duì)象需要需要依賴模塊的返回值進(jìn)行測(cè)試。也就是測(cè)試單元依賴了無(wú)法獲取的下游數(shù)據(jù)
比如:service中方法的測(cè)試需要dao中的訪問(wèn)數(shù)據(jù)庫(kù)操作并獲取其返回值,但是我們還沒(méi)有開(kāi)發(fā)完成對(duì)應(yīng)的dao方法,我們就可以mock一個(gè)dao層的對(duì)象,將其行為設(shè)置為:當(dāng)調(diào)用其中的某個(gè)方法時(shí)返回一個(gè)設(shè)定的值。這樣我們對(duì)service的測(cè)試就可以不必受dao層的開(kāi)發(fā)速度影響。也符合只對(duì)service方法邏輯進(jìn)行測(cè)試。
原則
不需要對(duì)所有的單元測(cè)試都將對(duì)象進(jìn)行mock,只對(duì)上述使用場(chǎng)景介紹的相關(guān)場(chǎng)景使用mock。
在分層測(cè)試中,高層的測(cè)試設(shè)計(jì)可以基于以下假設(shè):底層的測(cè)試已保證底層對(duì)象的質(zhì)量,高層無(wú)需關(guān)心低層對(duì)象的內(nèi)部邏輯質(zhì)量。這種情況下高層可以對(duì)低層對(duì)象進(jìn)行mock。
常用框架
EasyMock?:早期比較流行的mock框架,它提供對(duì)接口的模擬,能夠通過(guò)錄制、回放、檢查三步來(lái)完成大體的測(cè)試過(guò)程,可以驗(yàn)證方法的調(diào)用種類、次數(shù)、順序,可以令 Mock 對(duì)象返回指定的值或拋出指定異常
Mockito:EasyMock之后流行的mock工具。相對(duì)EasyMock學(xué)習(xí)成本低,而且具有非常簡(jiǎn)潔的API,測(cè)試代碼的可讀性很高。
PowerMock:這個(gè)工具是在EasyMock和Mockito上擴(kuò)展出來(lái)的,目的是為了解決EasyMock和Mockito不能解決的問(wèn)題,比如對(duì)static, final, private方法均不能mock。
其實(shí)測(cè)試架構(gòu)設(shè)計(jì)良好的代碼,一般并不需要這些功能,但如果是在已有項(xiàng)目上增加單元測(cè)試,老代碼有問(wèn)題且不能改時(shí),就不得不使用這些功能了。PowerMock 在擴(kuò)展功能時(shí)完全采用和被擴(kuò)展的框架相同的 API, 熟悉 PowerMock 所支持的模擬框架的開(kāi)發(fā)者會(huì)發(fā)現(xiàn) PowerMock 非常容易上手。PowerMock 的目的就是在當(dāng)前已經(jīng)被大家所熟悉的接口上通過(guò)添加極少的方法和注釋來(lái)實(shí)現(xiàn)額外的功能。目前PowerMock 僅擴(kuò)展了 EasyMock 和 mockito,需要和EasyMock或Mockito配合一起使用。
Jmockit:JMockit 是一個(gè)輕量級(jí)的mock框架是用以幫助開(kāi)發(fā)人員編寫(xiě)測(cè)試程序的一組工具和API,該項(xiàng)目完全基于 Java 5 SE 的 java.lang.instrument 包開(kāi)發(fā),內(nèi)部使用 ASM 庫(kù)來(lái)修改Java的Bytecode。
Jmockit功能和PowerMock類似,某些功能甚至更為強(qiáng)大,但個(gè)人感覺(jué)其代碼的可讀性并不強(qiáng)。
mock框架有好多,我們?cè)谶x用mock框架時(shí)可以根據(jù)使用環(huán)境使用相對(duì)的mock框架,不過(guò)在正常情況下,個(gè)人感覺(jué)mockito還是不錯(cuò)的:代碼可讀性強(qiáng),易于上手,功能絕大數(shù)項(xiàng)目的單元測(cè)試都?jí)蛴茫恍枰蕾嚻渌M件。這或許也是mockito這么流行的原因吧。
refer:博客 博客


近期精彩內(nèi)容推薦:??
?世界上五個(gè)最不務(wù)正業(yè)的科學(xué)家!
?魂斗羅只有128KB為何可以實(shí)現(xiàn)那么長(zhǎng)的劇情

