單元測試中mock的使用及mock神器jmockit實(shí)踐
在最近的r應(yīng)用的單元測試中,經(jīng)常需要用到mock,可以說mock在ut (unit test)中是無處不在的。而在r的ut實(shí)踐中也找到了一種很簡潔的mock方式,不僅解決了ut中所有需要mock的地方,而且可以很少量的代碼來完成mock。詳見下文。
一.Mock的使用場景:
比如以下場景:
1. mock掉外部依賴的應(yīng)用的HSF service的調(diào)用,比如uic,tp 的hsf服務(wù)依賴。
2. 對DAO層(訪問mysql、oracle、tair、tfs等底層存儲)的調(diào)用mock等。
3. 對系統(tǒng)間異步交互notify消息的mock。
4. 對method_A里面調(diào)用到的method_B 的mock 。
5. 對一些應(yīng)用里面自己的 class(abstract, final, static),interface,annotation ,enum,native等的mock。
二. Mock工具的原理:
mock工具工作的原理大都如下:
1. record階段:錄制期望。也可以理解為數(shù)據(jù)準(zhǔn)備階段。創(chuàng)建依賴的class 或interface或method ,模擬返回的數(shù)據(jù),及調(diào)用的次數(shù)等。
2. replay階段:通過調(diào)用被測代碼,執(zhí)行測試。期間會(huì)invoke 到 第一階段record的mock對象或方法。
3. verify階段:驗(yàn)證。可以驗(yàn)證調(diào)用返回是否正確。及mock的方法調(diào)用次數(shù),順序等。
三. 當(dāng)前的一些Mock工具的比較:
歷史曾經(jīng)或當(dāng)前比較流行的Mock工具有EasyMock、jMock、Mockito、Unitils Mock、PowerMock、jmockit等工具。
他們的功能對比如下:
從這里可以看到,當(dāng)前為什么jmockit為什么這么火爆了!所以我們的UT中的mock工具也選擇了目前無所不能的jmockit。
而在使用的過程中,感覺到j(luò)mockit的 Auto-injection of mocks 及 Special fields for "any" argument matching 及各種有用的 Annotation 給測試代碼精簡和測試效率提升帶來了實(shí)實(shí)在在的好處。
@Injectable private ConfirmGoodsService confirmGoodsService ; |
一個(gè)Annotation就搞定了所有的配置,加載等問題。直接復(fù)用開發(fā)代碼里面的bean,節(jié)省了大量的代碼。
另外 @Tested RefundManagerImpl refundManagerImpl = new RefundManagerImpl();
這里也用到了注解 @Tested 表示被測試的class 。
另外還有常用的注解:@Mocked,@NonStrict等。
而這段代碼就是mock的核心:錄制被mock的method的行為及期望返回:
new Expectations(){ { confirmGoodsService.queryConfirmToSellerRefundFee(anyLong); result = feeResultDOmock; times = 1; } } ; |
其中
result 可以返回任意需要的測試類型;
times 表示期望被調(diào)用的次數(shù)。
是不是看起來非常簡潔明了。
而上面該段代碼如果 換成基于狀態(tài)的mockup 代碼如下:
采用MockUp的方式,可以mock任意的mock對象或方法,因?yàn)樗苯痈膶懥嗽璵ethod的實(shí)現(xiàn)邏輯,直接返回需要的數(shù)據(jù)。
這也是jmockit彪悍的地方之一。
最后數(shù)據(jù)回收,防止各個(gè)testcase的mock相互影響的方式:
Mockit.tearDownMocks();
這一步也可以省略。
還要重點(diǎn)介紹的就是mock期望里面的入?yún)?any。
這個(gè)any系列的萬能入?yún)㈩愋停部梢怨?jié)省很多mock代碼,可以高效的準(zhǔn)備任何入?yún)㈩愋汀?/p>
以上,一個(gè)最簡單的,也最實(shí)用的jmockit的示例。
jmockit的更多,對interface及method的單元測試的示例,將在后續(xù)總結(jié)匯總。
六、 Jmockit自帶的code coverage :
工程的 pom文件中引入 jmockit-coverage 后,本地eclipse啟動(dòng)單元測試后, 會(huì)自動(dòng)統(tǒng)計(jì)單元測試的代碼覆蓋率。關(guān)于行覆蓋,方法覆蓋,類覆蓋,分支邏輯覆蓋等各種數(shù)據(jù)都可以看到。
IDE啟動(dòng)UT時(shí)候,加載 code coverage 組件,
點(diǎn)擊進(jìn)去,可以看到具體的覆蓋邏輯:
其中綠色部分表示源代碼被run過。
代碼覆蓋對指導(dǎo)單元測試的測試邏輯,覆蓋等提供了直觀的指示。
以上,就是在單元測試中mock技術(shù)的應(yīng)用:Jmockit的使用介紹及實(shí)際應(yīng)用示例。它在單元測試中確實(shí)可以很少的代碼mock掉外部依賴,提高ut的效率,并且 自帶的code coverage可很方便的看到ut對被測代碼的覆蓋效果,指導(dǎo)測試設(shè)計(jì)。
posted on 2013-07-25 10:40 順其自然EVO 閱讀(8136) 評論(0) 編輯 收藏 所屬分類: 測試學(xué)習(xí)專欄