EasyMock簡單用
在實際編寫unit test的過程中,很多情況下我們會需要使用其他的組件(如和數據庫相關的測試)。當我們是使用第三方提供的組件時,這并不是太大的問題,因為我們可以假設他們是無錯的。但是一旦這些組件是我們自己的組件時,問題就暴露出來了。
“單元測試出錯了,但到底是誰的錯。我的?他的?”,這種情況顯然違反了測試的獨立性原則。出現這種情況使得這個測試無法確切的指出是那個單元出現了問題,照成了排錯的困難,而且也浪費了時間。同時,過分的將單元的測試代碼依賴于其他單元,也照成了其他一些很現實的問題:
在所依賴的單元完成之前,無法順利的編寫單元測試。
產生環境的依賴性,如運行一個HttpServletRequest處理器的測試代碼必須啟動一個servlet容器。
所有這些問題,都可以使用Mock Object來解決。使用它的前提是,所依賴單元的接口必須定義清楚。而EasyMock正是為了這一目的而產生的。
使用目的
通過模擬unit test所需要的組件,已達到隔離各個unit test的目的。目前的版本1.1,它所需要的環境是jdk1.3.1以上和junit3.8.1以上。
可以從http://sourceforge.net/projects/easymock/處下載。
用法
1. EasyMock采用“記錄-----回放”的工作模式,基本使用步驟:
- 創建Mock對象的控制對象Control。
- 從控制對象中獲取所需要的Mock對象。
- 記錄測試方法中所使用到的方法和返回值。
- 設置Control對象到“回放”模式。
- 進行測試。
- 在測試完畢后,確認Mock對象已經執行了剛才定義的所有操作。
2. 使用舉例:假設需要測試的對象是RequestUtil,所需要測試的方法為getBoolean。此時我們需要模擬一個HttpServletRequest對象。
public void testGetStringHttpServletRequestString() {
public void testGetBoolean() {
//創建Mock對象的控制器
MockControl control= MockControl.createControl( HttpServletRequest.class);
//獲取Mock對象
HttpServletRequest mock= (HttpServletRequest)control.getMock();
//設置getBoolean中要使用的方法和返回值
control.expectAndReturn( mock.getParameter( "test"), null);
//設置控制器為replay模式
control.replay();
//執行測試
assertNull( RequestUtil.getString( mock, "test"));
//確認
control.verify();
}
}
通過EasyMock,執行這段測試代碼完全不需要啟動一個servlet容器,在命令行的方式下即可完成,非常的方便。
3. 記錄需要使用的Mock的行為。在使用一個Mock對象之前,需要設置我們要用到的方法,以及每個方法的返回值。對于那些沒有設置的方法,一旦調用(控制器處于replay模式),EasyMock就會拋出異常。記錄一個方法,通常可以分成2步:首先,如同使用正常對象調用這個方法;然后,使用控制器的setReturnValue函數設置即可。在1.1中,提供了expectAndReturn函數,使得2步可以合而為一。主要的函數大致如下:
- expectAndReturn,設置期望調用的函數,以及返回值
- expectAndThrow,設置期望調用的函數,同時期望該次調用拋出異常
- setReturnValue,設置上一次調用的返回值(如上次調用時,request.getparameter( “test”),此處設置request.getparameter( “test”)的返回值)
- setThrowable,設置上次調用拋出的異常
在EasyMock中還可以設置調用所執行的次數,具體細節請參見對應的javaDoc。
4. 使用舉例:
MockControl control= MockControl.createControl( HttpServletRequest.class);
HttpServletRequest mock= (HttpServletRequest)control.getMock();
mock.getParameter( "test");
//設置第一次調用request.getParameter的返回值
control.setReturnValue( null, 1);
//設置第二次調用request.getParameter的返回值
control.setReturnValue("this is a test", 1);
control.replay();
assertEquals( RequestUtil.getString( mock, "test", "haha"), "haha");
assertEquals( RequestUtil.getString( mock, "test"), "this is a test");
control.verify();
5. 在Mock對象使用結束后,務必調用控制器的verify函數,以確認Mock對象的方法得到了調用。
6. 調用方法的次序,使用Strict。有時,測試代碼依賴于被依賴組件的方法的次序。如在測試與數據庫相關代碼時,測試代碼很有可能是這樣的次序:先打開數據庫鏈接,執行操作,關閉鏈接。為了更好的測試這樣的代碼,可以使用MockControl.createStrictControl()來創建一個嚴格的Mock對象控制器,在其中,他會規定Mock出來的對象的調用次序。
以上是EasyMock的主要使用,至于其他的用法,請參見具體的文檔。
PS:當自己動手實現Mock對象時,不要在Mock對象中實現業務邏輯。
posted @ 2007-10-05 15:33 patsYang 閱讀(289) | 評論 (0) | 編輯 收藏