我和我追逐的夢
easymock并不是萬能的,在使用easymock時有一些限制需要注意。
(1) Object方法的限制
我們都知道java是一個單根繼承體系,Object是所有類的基類。在Object類上有幾個基本的方法,easymock是不能改變其行為的:equals(), hashCode()和toString()。
即對于easymock創(chuàng)建的mock對象,其equals(), hashCode()和toString()三個方法的行為時已經(jīng)固定了點,不能通過Easymock.expect()來指定這三個方法的行為,即使這三個方法是接口定義的一部分。
我們來先看一個例子:
execute()方法將為我們打印出toString()和hashCode()方法的結(jié)果。
測試案例testDefaultBehavior()將為我們打印出mock對象默認(rèn)的行為,輸出如下:
service.toString() = EasyMock for interface net.sourcesky.study.easymock.tutorial.LimitationTest$Service service.hashCode() = 26208195
可見easymock內(nèi)部已經(jīng)做好了toString()和hashCode()實現(xiàn)。
在測試案例testCustomizedBehavior()中,我們試圖通過EasyMock.expect()來指定toString()和hashCode()的行為,但是運行時遭遇錯誤:
java.lang.IllegalStateException: no last call on a mock available at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:521) at org.easymock.EasyMock.expect(EasyMock.java:499) at net.sourcesky.study.easymock.tutorial.LimitationTest.testCustomizedBehavior(LimitationTest.java:51) ...
從"no last call on a mock available"的描述上看,easymock根本沒有把對toString()方法的調(diào)用記錄(record)下來作為一個對mock對象的調(diào)用。
因此,在使用mock對象時,請注意equals(), hashCode()和toString()三個方法無法更改其行為。
(2) class mock的限制
相對于interface mock,class mock下easymock限制更多,除了上面談到的equals(), hashCode()和toString()三個方法外,還有以下限制:
1. final 方法不能被mock 2. private 方法不能對mock
(3) 靜態(tài)方法
對于靜態(tài)方法,easymock也無法mock其行為。
由于這個限制,當(dāng)被測試類中有靜態(tài)方法調(diào)用時,典型如單例方法調(diào)用,lookup方式的依賴查找,easymock就會力不從心。從這個角度上,推薦盡量使用IOC 控制反轉(zhuǎn)/ DI依賴注入的方式來實現(xiàn)依賴的獲取,而不要使用lookup的主動查找方式。
實際開發(fā)中,當(dāng)發(fā)現(xiàn)有因為靜態(tài)方法的限制從而導(dǎo)致easymock無法mock我們期望的行為,造成測試案例"不好寫",“寫不下去”時,請換個角度思考:為什么要用靜態(tài)方法?可不可以改成注入?
(4) 解決的方法
如果由于某些原因必須使用靜態(tài)方法或者定制final, private方法的行為,則可以考慮搭配其他mock框架來完成功能。
以靜態(tài)方法方法為例,一個典型的使用范例是:使用jmockit來定制靜態(tài)方法的行為,指定其返回easymock創(chuàng)建的mock對象,然后使用easymock的標(biāo)準(zhǔn)方式定制這個mock對象的行為。
posted on 2010-11-25 11:12 sky ao 閱讀(3305) 評論(0) 編輯 收藏 所屬分類: software test
Powered by: BlogJava Copyright © sky ao