隨筆 - 3, 文章 - 1, 評(píng)論 - 2, 引用 - 0
          數(shù)據(jù)加載中……

          2007年10月5日

          EasyMock簡(jiǎn)單用

                  在實(shí)際編寫(xiě)unit test的過(guò)程中,很多情況下我們會(huì)需要使用其他的組件(如和數(shù)據(jù)庫(kù)相關(guān)的測(cè)試)。當(dāng)我們是使用第三方提供的組件時(shí),這并不是太大的問(wèn)題,因?yàn)槲覀兛梢约僭O(shè)他們是無(wú)錯(cuò)的。但是一旦這些組件是我們自己的組件時(shí),問(wèn)題就暴露出來(lái)了。

          “單元測(cè)試出錯(cuò)了,但到底是誰(shuí)的錯(cuò)。我的?他的?”,這種情況顯然違反了測(cè)試的獨(dú)立性原則。出現(xiàn)這種情況使得這個(gè)測(cè)試無(wú)法確切的指出是那個(gè)單元出現(xiàn)了問(wèn)題,照成了排錯(cuò)的困難,而且也浪費(fèi)了時(shí)間。同時(shí),過(guò)分的將單元的測(cè)試代碼依賴于其他單元,也照成了其他一些很現(xiàn)實(shí)的問(wèn)題:

          在所依賴的單元完成之前,無(wú)法順利的編寫(xiě)單元測(cè)試。

          產(chǎn)生環(huán)境的依賴性,如運(yùn)行一個(gè)HttpServletRequest處理器的測(cè)試代碼必須啟動(dòng)一個(gè)servlet容器。

          所有這些問(wèn)題,都可以使用Mock Object來(lái)解決。使用它的前提是,所依賴單元的接口必須定義清楚。而EasyMock正是為了這一目的而產(chǎn)生的。

          使用目的

                 通過(guò)模擬unit test所需要的組件,已達(dá)到隔離各個(gè)unit test的目的。目前的版本1.1,它所需要的環(huán)境是jdk1.3.1以上和junit3.8.1以上。

          可以從http://sourceforge.net/projects/easymock/處下載。

          用法

          1.       EasyMock采用“記錄-----回放”的工作模式,基本使用步驟:

          -          創(chuàng)建Mock對(duì)象的控制對(duì)象Control

          -          從控制對(duì)象中獲取所需要的Mock對(duì)象。

          -          記錄測(cè)試方法中所使用到的方法和返回值。

          -          設(shè)置Control對(duì)象到“回放”模式。

          -          進(jìn)行測(cè)試。

          -          在測(cè)試完畢后,確認(rèn)Mock對(duì)象已經(jīng)執(zhí)行了剛才定義的所有操作。

          2.       使用舉例:假設(shè)需要測(cè)試的對(duì)象是RequestUtil,所需要測(cè)試的方法為getBoolean。此時(shí)我們需要模擬一個(gè)HttpServletRequest對(duì)象。

          public void testGetStringHttpServletRequestString() {

          public void testGetBoolean() {

             //創(chuàng)建Mock對(duì)象的控制器

             MockControl  control= MockControl.createControl( HttpServletRequest.class);

             //獲取Mock對(duì)象

             HttpServletRequest  mock= (HttpServletRequest)control.getMock();

             //設(shè)置getBoolean中要使用的方法和返回值

          control.expectAndReturn( mock.getParameter( "test"), null);
                      
                  
          //設(shè)置控制器為replay模式

                  control.replay();

                  //執(zhí)行測(cè)試

                  assertNull( RequestUtil.getString( mock, "test"));

                  //確認(rèn)

                  control.verify();

              }

          }

              通過(guò)EasyMock,執(zhí)行這段測(cè)試代碼完全不需要啟動(dòng)一個(gè)servlet容器,在命令行的方式下即可完成,非常的方便。

          3.       記錄需要使用的Mock的行為。在使用一個(gè)Mock對(duì)象之前,需要設(shè)置我們要用到的方法,以及每個(gè)方法的返回值。對(duì)于那些沒(méi)有設(shè)置的方法,一旦調(diào)用(控制器處于replay模式),EasyMock就會(huì)拋出異常。記錄一個(gè)方法,通常可以分成2:首先,如同使用正常對(duì)象調(diào)用這個(gè)方法;然后,使用控制器的setReturnValue函數(shù)設(shè)置即可。在1.1中,提供了expectAndReturn函數(shù),使得2步可以合而為一。主要的函數(shù)大致如下:

          -          expectAndReturn,設(shè)置期望調(diào)用的函數(shù),以及返回值

          -          expectAndThrow,設(shè)置期望調(diào)用的函數(shù),同時(shí)期望該次調(diào)用拋出異常

          -          setReturnValue,設(shè)置上一次調(diào)用的返回值(如上次調(diào)用時(shí),request.getparameter( “test”),此處設(shè)置request.getparameter( “test”)的返回值)

          -          setThrowable,設(shè)置上次調(diào)用拋出的異常

          EasyMock中還可以設(shè)置調(diào)用所執(zhí)行的次數(shù),具體細(xì)節(jié)請(qǐng)參見(jiàn)對(duì)應(yīng)的javaDoc

          4.       使用舉例:

          MockControl  control= MockControl.createControl( HttpServletRequest.class);

          HttpServletRequest  mock= (HttpServletRequest)control.getMock();

          mock.getParameter( "test");

          //設(shè)置第一次調(diào)用request.getParameter的返回值

          control.setReturnValue( null, 1);

          //設(shè)置第二次調(diào)用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對(duì)象使用結(jié)束后,務(wù)必調(diào)用控制器的verify函數(shù),以確認(rèn)Mock對(duì)象的方法得到了調(diào)用。

          6.       調(diào)用方法的次序,使用Strict。有時(shí),測(cè)試代碼依賴于被依賴組件的方法的次序。如在測(cè)試與數(shù)據(jù)庫(kù)相關(guān)代碼時(shí),測(cè)試代碼很有可能是這樣的次序:先打開(kāi)數(shù)據(jù)庫(kù)鏈接,執(zhí)行操作,關(guān)閉鏈接。為了更好的測(cè)試這樣的代碼,可以使用MockControl.createStrictControl()來(lái)創(chuàng)建一個(gè)嚴(yán)格的Mock對(duì)象控制器,在其中,他會(huì)規(guī)定Mock出來(lái)的對(duì)象的調(diào)用次序。

          以上是EasyMock的主要使用,至于其他的用法,請(qǐng)參見(jiàn)具體的文檔。

          PS:當(dāng)自己動(dòng)手實(shí)現(xiàn)Mock對(duì)象時(shí),不要在Mock對(duì)象中實(shí)現(xiàn)業(yè)務(wù)邏輯。

          posted @ 2007-10-05 15:33 patsYang 閱讀(289) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 桓仁| 绿春县| 太仓市| 楚雄市| 洞口县| 北安市| 巫溪县| 时尚| 扬中市| 麟游县| 平陆县| 桂东县| 大姚县| 桦南县| 宝丰县| 神木县| 凤翔县| 施秉县| 清丰县| 英山县| 花垣县| 辽阳县| 尼木县| 济宁市| 高唐县| 甘南县| 尉犁县| 松滋市| 石家庄市| 新兴县| 南昌县| 宣武区| 宣汉县| 怀远县| 民乐县| 洞口县| 璧山县| 永寿县| 花莲县| 秦皇岛市| 萝北县|