Sky's blog

          我和我追逐的夢

          常用鏈接

          統計

          其他鏈接

          友情鏈接

          最新評論

          easymock教程-mock的限制

              easymock并不是萬能的,在使用easymock時有一些限制需要注意。

          (1) Object方法的限制

              我們都知道java是一個單根繼承體系,Object是所有類的基類。在Object類上有幾個基本的方法,easymock是不能改變其行為的:equals(), hashCode()和toString()。

              即對于easymock創(chuàng)建的mock對象,其equals(), hashCode()和toString()三個方法的行為時已經固定了點,不能通過Easymock.expect()來指定這三個方法的行為,即使這三個方法是接口定義的一部分。

              我們來先看一個例子:

             public class Business {
                  
          private Service service;

                  
          public void execute() {
                      System.out.println(
          "service.toString() = " + service.toString());
                      System.out.println(
          "service.hashCode() = " + service.hashCode());
                  }


                  
          public void setService(Service service) {
                      
          this.service = service;
                  }

              }


              
          private interface Service {

                  
          public String toString();

                  
          public int hashCode();
              }

              execute()方法將為我們打印出toString()和hashCode()方法的結果。

          public class LimitationTest {

              
          private Business      business;

              
          private IMocksControl mocksControl;

              
          private Service       service;

              @Before
              
          public void init() {
                  business 
          = new Business();
                  mocksControl 
          = EasyMock.createStrictControl();
                  service 
          = mocksControl.createMock(Service.class);
                  business.setService(service);
              }


              @Test
              
          public void testDefaultBehavior() {
                  business.execute();
              }


              @Test
              
          public void testCustomizedBehavior() {

                  EasyMock.expect(service.toString()).andReturn(
          "Customized toString");
                  EasyMock.expect(service.hashCode()).andReturn(
          100000);
                  mocksControl.replay();

                  business.execute();
                  mocksControl.verify();
              }

          }

              測試案例testDefaultBehavior()將為我們打印出mock對象默認的行為,輸出如下:

          service.toString() = EasyMock for interface net.sourcesky.study.easymock.tutorial.LimitationTest$Service
          service.hashCode() = 26208195

              可見easymock內部已經做好了toString()和hashCode()實現。

              在測試案例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()方法的調用記錄(record)下來作為一個對mock對象的調用。

              因此,在使用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其行為。

              由于這個限制,當被測試類中有靜態(tài)方法調用時,典型如單例方法調用,lookup方式的依賴查找,easymock就會力不從心。從這個角度上,推薦盡量使用IOC 控制反轉/ DI依賴注入的方式來實現依賴的獲取,而不要使用lookup的主動查找方式。

              實際開發(fā)中,當發(fā)現有因為靜態(tài)方法的限制從而導致easymock無法mock我們期望的行為,造成測試案例"不好寫",“寫不下去”時,請換個角度思考:為什么要用靜態(tài)方法?可不可以改成注入?

          (4) 解決的方法

              如果由于某些原因必須使用靜態(tài)方法或者定制final, private方法的行為,則可以考慮搭配其他mock框架來完成功能。

              以靜態(tài)方法方法為例,一個典型的使用范例是:使用jmockit來定制靜態(tài)方法的行為,指定其返回easymock創(chuàng)建的mock對象,然后使用easymock的標準方式定制這個mock對象的行為。

           

          posted on 2010-11-25 11:12 sky ao 閱讀(3316) 評論(0)  編輯  收藏 所屬分類: software test

          主站蜘蛛池模板: 杭锦后旗| 郴州市| 阜南县| 资溪县| 奎屯市| 辽源市| 建平县| 焉耆| 长武县| 商城县| 大名县| 德阳市| 和静县| 五家渠市| 徐闻县| 康定县| 安宁市| 玉田县| 富锦市| 垣曲县| 蛟河市| 舒兰市| 辛集市| 娱乐| 迁西县| 镇远县| 成都市| 济阳县| 宁德市| 寻甸| 八宿县| 兰考县| 宁国市| 志丹县| 鄄城县| 呼和浩特市| 保德县| 个旧市| 哈巴河县| 新兴县| 吴忠市|