posts - 11,  comments - 28,  trackbacks - 0

          JpetStore提供了一個(gè)整套的測(cè)試代碼對(duì)于想進(jìn)行單元測(cè)試卻不知道如何進(jìn)行單元測(cè)試的人(me)來(lái)說(shuō),是一個(gè)很好的學(xué)習(xí)機(jī)會(huì)。
          JpetStore的單元測(cè)試代碼與它的系統(tǒng)源文件是獨(dú)立分離的,在test文件夾中。打開文件夾可以很清楚的發(fā)現(xiàn)該文件夾的內(nèi)容組成結(jié)構(gòu)與源文件基本一致。
          JpetStore分為領(lǐng)域?qū)樱╠omain),持久層(peristence),服務(wù)層(service),表現(xiàn)層(presentation),它的測(cè)試也分這幾個(gè)層來(lái)進(jìn)行。下面就按層來(lái)學(xué)習(xí)它的test。
          1、? 領(lǐng)域?qū)樱╠omain)
          由于領(lǐng)域?qū)拥拇a主要是用于在各層之間傳遞的類,所以,此層的測(cè)試代碼也比較簡(jiǎn)單,主要有兩個(gè)測(cè)試類,BeanTest.java與DomainFixture.java。
          BeanTest.java類主要是利用包c(diǎn)om.ibatis.common.beans的功能,來(lái)完成系統(tǒng)中所有bean(領(lǐng)域?qū)拥念惻c表現(xiàn)層的類)get與set方法的測(cè)試,避免遺漏。
          DomainFixture.java類主要是構(gòu)造兩個(gè)用于其他層進(jìn)行測(cè)試的領(lǐng)域?qū)嶓w。
          2、? 持久層(persistence)
          持久層主要是測(cè)試訪問(wèn)數(shù)據(jù)庫(kù)的代碼功能。主要可以分成三個(gè)類:PersistenceFixture、BasePersistenceTest和各種實(shí)際測(cè)試的類如:AccountDaoTest。
          PersistenceFixture類,這個(gè)類完成所有持久層代碼的數(shù)據(jù)庫(kù)的鏈接。
          BasePersistenceTest類,所有持久層類的父類,引用類PersistenceFixture,構(gòu)造一個(gè)DaoManager的實(shí)例,用于取得各實(shí)際測(cè)試類的Dao。
          AccountDaoTest類,具體測(cè)試持久層的類,通過(guò)一下語(yǔ)句得到dao,然后進(jìn)行測(cè)試。
          private AccountDao acctDao = (AccountDao)daoMgr.getDao(AccountDao.class);
          3、? 服務(wù)層(service)
          服務(wù)層由于需調(diào)用持久層來(lái)完成測(cè)試功能,所以,采用模擬對(duì)象(Mock Object)來(lái)完成。模擬對(duì)象的背后目的就是創(chuàng)建一個(gè)輕量級(jí)的、可控制的對(duì)象來(lái)代替測(cè)試中需要的真實(shí)對(duì)象,模擬真實(shí)對(duì)象的行為和功能,方便進(jìn)行分層測(cè)試。JpetStore主要采用的是JMock。具體的介紹見(http://www.jetmaven.net/contents/documents/j_jMock_intro.php)?
          public?class?AccountServiceTest?extends?MockObjectTestCase?{?
          ??
          ??
          public?void?testShouldVerifyGetAccountIsCalledByUsername()?{?
          ????Mock?mock?
          =?mock(AccountDao.class);//創(chuàng)建模擬對(duì)象?
          ??
          ????
          //定義所要模擬的函數(shù)的具體信息?
          ????mock.expects(once())//模擬對(duì)象要執(zhí)行的次數(shù)?
          ????????.method("getAccount")//模擬對(duì)象要執(zhí)行的函數(shù)?
          ????????.with(NOT_NULL)//函數(shù)的入口參數(shù)?
          ????????.will(returnValue(new?Account()));//函數(shù)的返回參數(shù)?
          ??
          AccountService?accountService?
          =?new?AccountService((AccountDao)?mock.proxy());?
          //根據(jù)模擬對(duì)象的代理完成模擬對(duì)象與實(shí)際對(duì)象的關(guān)聯(lián)?
          ????accountService.getAccount("cbegin");?
          ??}
          ?
          }
          ?
          ?????? 上面是服務(wù)層AccountService的其中一個(gè)函數(shù)的測(cè)試代碼。所有使用JMock的類必須繼承于MockObjectTestCase。它的具體使用方法已經(jīng)在備注中寫明。
          4、? 表現(xiàn)層(presentation)
          表現(xiàn)層和服務(wù)層的測(cè)試方法大致相同。首先通過(guò)模擬對(duì)象(mock object)模擬服務(wù)層,然后調(diào)用模擬對(duì)象完成實(shí)際的功能測(cè)試。下面是一個(gè)典型的bean的測(cè)試代碼?
          public?class?AccountBeanTest?extends?MockObjectTestCase?{?
          ??
          ??
          public?void?testShouldSuccessfullyCallServicesToCreateNewAccount()?{?
          ????Account?account?
          =?DomainFixture.newTestAccount();?
          ??
          ????Mock?accountServiceMock?
          =?mock(AccountService.class);?
          ??
          ????accountServiceMock.expects(once())?
          ????????.method(
          "insertAccount")?
          ????????.with(NOT_NULL);?
          ??
          ????accountServiceMock.expects(once())?
          ????????.method(
          "getAccount")?
          ????????.with(NOT_NULL)?
          ????????.will(returnValue(account));?
          ??
          ????Mock?catalogServiceMock?
          =?mock(CatalogService.class);?
          ??
          ????catalogServiceMock.expects(once())?
          ????????.method(
          "getProductListByCategory")?
          ????????.with(NOT_NULL)?
          ????????.will(returnValue(
          new?PaginatedArrayList(5)));?
          ??
          ????AccountBean?accountBean?
          =?new?AccountBean((AccountService)accountServiceMock.proxy(),?(CatalogService)catalogServiceMock.proxy());?
          ????accountBean.setAccount(account);?
          ??
          ????String?result?
          =?accountBean.newAccount();?
          ????assertEquals(AbstractBean.SUCCESS,?result);?
          ??}
          ?
          }
          ?
          ?
          通過(guò)學(xué)習(xí)JPetStoreShop的測(cè)試代碼,基本上可以學(xué)到這樣幾點(diǎn)
          1)? 測(cè)試代碼與實(shí)際代碼分離
          2)? 測(cè)試代碼與實(shí)際代碼的組成結(jié)構(gòu)相同,易于查看
          3)? 測(cè)試代碼要分層進(jìn)行
          4)? 領(lǐng)域?qū)又械腂eanTest.java類可以復(fù)用
          5)? 持久層的測(cè)試代碼類的關(guān)系可以學(xué)習(xí)
          6)? 服務(wù)層的Jmock中模擬對(duì)象(mock object)的使用方法
          ?
          本文只是簡(jiǎn)單的對(duì)JpetStoreShop中的代碼進(jìn)行了分析,包括測(cè)試代碼的組成以及基本關(guān)系,并未細(xì)化到測(cè)試代碼要測(cè)試哪些點(diǎn)。具體的測(cè)試點(diǎn)還需要參考其他書籍進(jìn)行學(xué)習(xí)。關(guān)于Jmock的學(xué)習(xí)見http://www.jetmaven.net/contents/documents/j_jMock_intro.php
          關(guān)于測(cè)試的心得見http://www.aygfsteel.com/AndersLin/archive/2006/06/12/52298.html
          posted on 2007-01-22 15:18 滌生 閱讀(3366) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(5)

          隨筆檔案

          UML

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 浮梁县| 密山市| 鄂托克前旗| 揭东县| 宁乡县| 历史| 扶绥县| 清原| 铁力市| 资兴市| 黄大仙区| 衡阳市| 吉木萨尔县| 龙井市| 新田县| 丹江口市| 利津县| 深圳市| 缙云县| 瑞安市| 桦南县| 彭阳县| 营山县| 玉山县| 青龙| 晋江市| 花莲市| 花垣县| 和田县| 遂昌县| 香河县| 资溪县| 水富县| 马鞍山市| 新和县| 彰化市| 嫩江县| 集安市| 丽水市| 泰兴市| 绩溪县|