favey sky!

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            5 Posts :: 0 Stories :: 2 Comments :: 0 Trackbacks

          ecipse Spring 框架中進(jìn)行 JUnit 單元測(cè)試

          ?

          測(cè)試對(duì)于保證軟件開(kāi)發(fā)質(zhì)量有著非常重要的作用,單元測(cè)試更是必不可少, JUnit 是一個(gè)非常強(qiáng)大的單元測(cè)試包,可以對(duì)一個(gè) / 多個(gè)類(lèi)的單個(gè) / 多個(gè)方法測(cè)試,還可以將不同的 TestCase 組合成 TestSuit ,使測(cè)試任務(wù)自動(dòng)化。 Eclipse 同樣集成了 JUnit ,可以非常方便地編寫(xiě) TestCase

          一、???????????? JUnit 核心

          JUnit 的目的是協(xié)助您進(jìn)行單元測(cè)試( Unit Test ),并鼓勵(lì)您先寫(xiě)測(cè)試。

          JUnit 包括了以下的特性:

          對(duì)預(yù)期結(jié)果作斷言
          提供測(cè)試裝備的生成與銷(xiāo)毀
          易于組織與執(zhí)行測(cè)試
          圖型與文字介面的測(cè)試器

          ?

          JUnit 的核心類(lèi):TestCaseTestSuite以及BaseTestRunner,其中用的最多的就是TestCase,當(dāng)需要多個(gè)TestCase的時(shí)候就要?jiǎng)?chuàng)建一個(gè)TestSuite,而運(yùn)行TestSuite則要?jiǎng)?chuàng)建TestRunner,其關(guān)系如下:

          核心類(lèi)定義:

          ??????? TestCase (測(cè)試用例) —— 擴(kuò)展了JUnitTestCase類(lèi)的類(lèi)。它以testXXX方法的形式包含一個(gè)或多個(gè)測(cè)試。一個(gè)test case把具有公共行為的測(cè)試歸入一組。在本書(shū)的后續(xù)部分,當(dāng)我們提到測(cè)試的時(shí)候,我們指的是一個(gè)testXXX方法;當(dāng)我們提及test case的時(shí)候,我們指的是一個(gè)繼承自TestCase的類(lèi),也就是一組測(cè)試。

          ???????TestSuite (測(cè)試集合 ——一組測(cè)試。一個(gè)test suite是把多個(gè)相關(guān)測(cè)試歸入一組的便捷方式。例如,如果你沒(méi)有為TestCase定義一個(gè)test suite,那么JUnit就會(huì)自動(dòng)提供一個(gè)test suite,包含TestCase中所有的測(cè)試(本書(shū)稍后會(huì)細(xì)說(shuō))。

          ????????TestRunner (測(cè)試運(yùn)行器 ——執(zhí)行test suite的程序。JUnit提供了幾個(gè)test runner,你可以用它們來(lái)執(zhí)行你的測(cè)試。沒(méi)有TestRunner接口,只有一個(gè)所有test runner都繼承的BaseTestRunner。因此,當(dāng)我們編寫(xiě)TestRunner的時(shí)候,我們實(shí)際上指的是任何繼承BaseTestRunnertest runner類(lèi)。

          其中TesetCase主要有10個(gè)自己的方法:

          ?

          二、下面就以Eclipse中單個(gè)TestCase為例子講一下普通的JUnit測(cè)試:

          ??? 首先我們創(chuàng)建一個(gè) Java 工程,添加一個(gè) example.Hello 類(lèi),首先我們給 Hello 類(lèi)添加一個(gè) abs() 方法,作用是返回絕對(duì)值:

            下一步,我們準(zhǔn)備對(duì)這個(gè)方法進(jìn)行測(cè)試,確保功能正常。選中 Hello.java ,右鍵點(diǎn)擊,選擇 New->JUnit Test Case

             Eclipse 會(huì)詢(xún)問(wèn)是否添加 junit.jar 包,確定后新建一個(gè) HelloTest 類(lèi),用來(lái)測(cè)試 Hello 類(lèi)。

            選中 setUp() tearDown() ,然后點(diǎn)擊 “Next”

            選擇要測(cè)試的方法,我們選中 abs(int) 方法,完成后在 HelloTest.java 中輸入:

             JUnit 會(huì)以以下順序執(zhí)行測(cè)試:(大致的代碼

          try {
          HelloTest test = new HelloTest(); //
          建立測(cè)試類(lèi)實(shí)例
          test.setUp(); //
          初始化測(cè)試環(huán)境
          test.
          testAbs (); // 測(cè)試某個(gè)方法
          test.tearDown(); //
          清理資源
          }
          catch…


             setUp() 是建立測(cè)試環(huán)境,這里創(chuàng)建一個(gè) Hello 類(lèi)的實(shí)例; tearDown() 用于清理資源,如釋放打開(kāi)的文件等等。以 test 開(kāi)頭的方法被認(rèn)為是測(cè)試方法, JUnit 會(huì)依次執(zhí)行 testXxx() 方法。在 testAbs() 方法中,我們對(duì) abs() 的測(cè)試分別選擇正數(shù),負(fù)數(shù)和 0 ,如果方法返回值與期待結(jié)果相同,則 assertEquals 不會(huì)產(chǎn)生異常。

            如果有多個(gè) testXxx 方法, JUnit 會(huì)創(chuàng)建多個(gè) XxxTest 實(shí)例,每次運(yùn)行一個(gè) testXxx 方法, setUp() tearDown() 會(huì)在 testXxx 前后被調(diào)用,因此,不要在一個(gè) testA() 中依賴(lài) testB()

            直接運(yùn)行 Run->Run As->JUnit Test ,就可以看到 JUnit 測(cè)試結(jié)果:

            綠色表示測(cè)試通過(guò),只要有 1 個(gè)測(cè)試未通過(guò),就會(huì)顯示紅色并列出未通過(guò)測(cè)試的方法。可以試圖改變 abs() 的代碼,故意返回錯(cuò)誤的結(jié)果(比如 return n+1; ),然后再運(yùn)行 JUnit 就會(huì)報(bào)告錯(cuò)誤。

          三、在 Spring 中進(jìn)行 DAO 測(cè)試

          ??? Spring 提供了下列一些特定的JUnit框架擴(kuò)展:

          AbstractDependencyInjectionSpringContextTests— 這是一個(gè)針對(duì)所有測(cè)試的超類(lèi),其具體使用依賴(lài)于Spring上下文。

          AbstractSpringContextTests— 這是一個(gè)針對(duì)所有的JUnit測(cè)試情形的超類(lèi)。它使用一個(gè)Spring上下文。并且,一般在測(cè)試中不是直接使用它,而是使用AbstractDependencyInjectionSpringContextTests或者AbstractTransactionalSpringContextTests這樣的派生類(lèi)。

          AbstractTransactionalSpringContextTests— 這是一個(gè)針對(duì)所有測(cè)試的超類(lèi),我們一般把它應(yīng)用在事務(wù)相關(guān)的測(cè)試中。注意,一旦完成每個(gè)測(cè)試它就會(huì)正常地回滾事務(wù);而且你需要重載onSetUpInTransactiononTearDownInTransaction方法以便手工開(kāi)始并提交事務(wù)。

          AbstractTransactionalDataSourceSpringContextTests— 這是AbstractTransactionalSpringContextTests的一個(gè)子類(lèi),它使用了Spring的基于JDBCjdbcTemplate工具類(lèi)。

          所有上面這些擴(kuò)展將極大程度地簡(jiǎn)化在測(cè)試時(shí)對(duì)于相關(guān)操作的依賴(lài)性注入和事務(wù)管理。

          ?????? 下面就以一個(gè)用戶(hù) DAO 類(lèi) HibernateUserDao 類(lèi)中的一個(gè)方法 getPasswordByName(String userName) 進(jìn)行測(cè)試作為例子,其中的輸入就是用戶(hù)名,輸出就是用戶(hù)密碼:

          測(cè)試類(lèi):

          //HibernateUserDAOTest.java

          public class HibernateUserDAOTest extends AbstractTransactionalDataSourceSpringContextTests

          {

          ??? ApplicationContext applicationContext ;

          ??? HibernateUserDAO hub ;

          ???

          ??? @Override

          ??? protected String[] getConfigLocations()

          ??? {

          ?????? String[] config= new String[]{ "file:D:\\RfidStock2\\WebRoot\\WEB-INF\\classes\\applicationContext.xml" };

          ?????? return config;

          ??? }

          ???

          ??? public ApplicationContext getContext(String[] filePath)

          ??? {

          ?

          ?????? return new ClassPathXmlApplicationContext(filePath);

          ??? }

          ???

          ??????

          ??? public void testConfig() {???????

          ??????? assertNotNull( "spring-mock context has bean init()" , this .getConfigLocations());

          ??? }

          ???

          ???

          ???

          ??? @Test

          ??? public final void testGetPasswordByName() throws BaseException

          ??? {

          ?????? hub =(HibernateUserDAO)getContext(getConfigLocations()).getBean( "hibernateUserDAO" );

          ?????? assertEquals( "234" , hub . getPasswordByName ( "42" ));

          ??? }

          ???

          ??? public static void main(String[] args)

          ??? {

          ?????? TestRunner.run((Class<? extends TestCase>) HibernateUserDAO. class );

          ??? }

          ???

          }

          Spring 下由于要驅(qū)動(dòng) Spring ,所以測(cè)試類(lèi)要繼承 AbstractTransactionalDataSourceSpringContextTests 類(lèi),需要實(shí)現(xiàn)一個(gè)方法 String[] getConfigLocations() ,用這個(gè)方法來(lái)獲取 Spring 的配置文件,然后我通過(guò)寫(xiě) getContext(String[] filePath) 這個(gè)方法來(lái)獲取 Spring 的上下文,在這里我們要獲取待測(cè)試對(duì)象有兩種方法一種就是 setHibernateUserDAO() getHibernateUserDAO() 方法,另外一種就是通過(guò)上下文提取配置文件中定義的 Bean ,然后再獲取具體的方法。

          這個(gè)就是測(cè)試結(jié)果:

          posted on 2007-03-30 20:58 favey 閱讀(3313) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): JEE

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 丰宁| 临湘市| 前郭尔| 卫辉市| 仪征市| 宝鸡市| 乐亭县| 蒲城县| 赤城县| 遂昌县| 西畴县| 晋州市| 茶陵县| 册亨县| 古蔺县| 成武县| 永城市| 吉木乃县| 阳山县| 汝城县| 安陆市| 托克托县| 凌源市| 马关县| 石狮市| 新沂市| 千阳县| 襄汾县| 油尖旺区| 安岳县| 荥阳市| 兴海县| 册亨县| 吐鲁番市| 饶平县| 定结县| 永平县| 务川| 阿拉善左旗| 浦江县| 防城港市|