隨筆 - 23  文章 - 11  trackbacks - 0
          <2008年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          在WebWork2.2中和Spring的結(jié)合變得簡單了,WebWork的Action的也可以由Spring來管理。但是如何進(jìn)行測(cè)試了,在google上搜了一下,其代碼都是如下形式:
           1        Map params = new HashMap();
           2        params.put("a""test");
           3               Map paramCtx = new HashMap();
           4        paramCtx.put(ActionContext.PARAMETERS, params);
           5                ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("/organiz""new_depart", paramCtx, falsefalse);
           6        proxy.setExecuteResult(false);
           7        assertEquals(proxy.execute(), "success");
           8
           9        MyTestAction action = (MyTestAction) proxy.getAction();
          10        assertEquals(action.getA(), "test");

          該代碼執(zhí)行時(shí)會(huì)報(bào)錯(cuò)誤,查看了一下源代碼應(yīng)該加入
          1paramCtx.put(ActionContext.DEV_MODE, Boolean.FALSE);

          其次需要加載spring的applicationContext,代碼如下:
          1SpringObjectFactory objectFactory = new SpringObjectFactory();
          2        ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
          3        objectFactory.setApplicationContext(appContext);
          4        ObjectFactory.setObjectFactory(objectFactory);


          posted @ 2012-02-28 22:53 小小~咖啡豆 閱讀(192) | 評(píng)論 (0)編輯 收藏
          1.編譯亂碼,設(shè)置編譯的字符集編碼和環(huán)境編碼
          <plugin>
                          <groupId>org.apache.maven.plugins</groupId>
                          <artifactId>maven-compiler-plugin</artifactId>
                          <version>2.3.2</version>
                          <configuration>
                              <source>1.4</source>
                              <target>1.4</target>
                              <encoding>UTF-8</encoding>
                          </configuration>
                      </plugin>
          設(shè)置環(huán)境變量MAVEN_OPTS=-Xms64m -Xmx128m -Dfile.encoding=UTF-8
          2.運(yùn)行mvn test時(shí)亂碼(IDE上運(yùn)行TestCase時(shí)OK,但是運(yùn)行maven test亂碼,結(jié)果測(cè)試不通過)修改pom.xml增加如下內(nèi)容即可
          <plugin>
                          <groupId>org.apache.maven.plugins</groupId>
                          <artifactId>maven-surefire-plugin</artifactId>
                          <version>2.7.2</version>
                          <configuration>
                              <forkMode>once</forkMode>
                              <argLine>-Dfile.encoding=UTF-8</argLine>
                              <systemProperties>
                                  <property>
                                      <name>net.sourceforge.cobertura.datafile</name>
                                      <value>target/cobertura/cobertura.ser</value>
                                  </property>
                              </systemProperties>
                          </configuration>
                      </plugin>
          posted @ 2011-06-30 02:15 小小~咖啡豆 閱讀(1532) | 評(píng)論 (1)編輯 收藏
          <title>屏蔽鼠標(biāo)右鍵、Ctrl+n、shift+F10、F5刷新、退格鍵</title>
          </head>
          <body onkeydown="KeyDown()"
          oncontextmenu="event.returnValue=false">

          <script language="Javascript"><!--
          //屏蔽鼠標(biāo)右鍵、Ctrl+n、shift+F10、F5刷新、退格鍵
          //Author: meizz(梅花雨) 2002-6-18

          function KeyDown(){
          if ((window.event.altKey)&&
          ((window.event.keyCode==37)|| //屏蔽 Alt+ 方向鍵 ←
          (window.event.keyCode==39))){ //屏蔽 Alt+ 方向鍵 →
          alert("不準(zhǔn)你使用ALT+方向鍵前進(jìn)或后退網(wǎng)頁!");
          event.returnValue=false;
          }

          /* 注:這還不是真正地屏蔽 Alt+ 方向鍵,
          因?yàn)?Alt+ 方向鍵彈出警告框時(shí),按住 Alt 鍵不放,
          用鼠標(biāo)點(diǎn)掉警告框,這種屏蔽方法就失效了。以后若
          有哪位高手有真正屏蔽 Alt 鍵的方法,請(qǐng)告知。*/

          if ((event.keyCode==8) || //屏蔽退格刪除鍵
          (event.keyCode==116)|| //屏蔽 F5 刷新鍵
          (event.ctrlKey && event.keyCode==82)){ //Ctrl + R
          event.keyCode=0;
          event.returnValue=false;
          }
          if ((event.ctrlKey)&&(event.keyCode==78)) //屏蔽 Ctrl+n
          event.returnValue=false;
          if ((event.shiftKey)&&(event.keyCode==121)) //屏蔽 shift+F10
          event.returnValue=false;
          if (window.event.srcElement.tagName == "A" && window.event.shiftKey)
          window.event.returnValue = false; //屏蔽 shift 加鼠標(biāo)左鍵新開一網(wǎng)頁
          if ((window.event.altKey)&&(window.event.keyCode==115)){ //屏蔽Alt+F4
          window.showModelessDialog("about:blank","","dialogWidth:1px;dialogheight:1px");
          return false;}
          }
          /* 另外可以用 window.open 的方法屏蔽 IE 的所有菜單
          第一種方法:
          window.open("你的.htm", "","toolbar=no,location=no,directories=no,menubar=no,scrollbars=no,resizable=yes,status=no,top=0,left=0")
          第二種方法是打開一個(gè)全屏的頁面:
          window.open("你的.asp", "", "fullscreen=yes")
          */
          // --></script>
          <h2 align=center>屏蔽鼠標(biāo)右鍵、Ctrl+n、shift+F10、F5刷新、退格鍵</h2>
          </body>
          </html>

          <div style="position: absolute; top: 10; right: 10; width: 148; height: 18;cursor:hand">
          <input type="button" name="Button" value="查看源代碼" onClick= 'window.location = "view-source:" + window.location.href'></div>
          posted @ 2008-09-23 16:12 小小~咖啡豆 閱讀(529) | 評(píng)論 (0)編輯 收藏

          數(shù)據(jù)庫測(cè)試

          在創(chuàng)建企業(yè)級(jí)應(yīng)用的時(shí)候,數(shù)據(jù)層的單元測(cè)試因?yàn)槠鋸?fù)雜性往往被遺棄,Unitils大大降低了測(cè)試的復(fù)雜性,使得數(shù)據(jù)庫的測(cè)試變得容易并且易維護(hù)。已下介紹databasemodule和dbunitmodule進(jìn)行數(shù)據(jù)庫的單元測(cè)試。

          用dbUnit管理測(cè)試數(shù)據(jù)

          數(shù)據(jù)庫的測(cè)試應(yīng)該在單元測(cè)試數(shù)據(jù)庫上運(yùn)行,單元測(cè)試數(shù)據(jù)庫給我們提供了一個(gè)完整的并有著很好細(xì)粒度控制的測(cè)試數(shù)據(jù),DbUnitModule是在dbunit的基礎(chǔ)上進(jìn)一步的為數(shù)據(jù)庫的測(cè)試提供數(shù)據(jù)集的支持。

          加載測(cè)試數(shù)據(jù)集

          讓我們以UserDAO中一個(gè)簡單的方法findByName(檢查姓氏和名字)為例子開始介紹。他的單元測(cè)試如下:

          @DataSet

          public class UserDAOTest extends UnitilsJUnit4 {

              @Test

              public void testFindByName() {

                  User result = userDao.findByName("doe", "john");

                  assertPropertyLenEquals("userName", "jdoe", result);

              }

              @Test

              public void testFindByMinimalAge() {

                  List<User> result = userDao.findByMinimalAge(18);        

                  assertPropertyLenEquals("firstName", Arrays.asList("jack"), result);

              }

          }

              @DateSet 注解表示了測(cè)試需要尋找dbunit的數(shù)據(jù)集文件進(jìn)行加載,如果沒有指明數(shù)據(jù)集的文件名,則Unitils自動(dòng)在class文件的同目錄下加載文件名為 className.xml的數(shù)據(jù)集文件。(這種定義到class上面的數(shù)據(jù)集稱為class級(jí)別的數(shù)據(jù)集)

              數(shù)據(jù)集 文件必須是dbunit的FlatXMLDataSet文件格式,其中包含了所要測(cè)試的數(shù)據(jù)。測(cè)試數(shù)據(jù)庫表中所有的內(nèi)容將會(huì)被刪除,然后再插入數(shù)據(jù)集中的 數(shù)據(jù)。如果表不屬于數(shù)據(jù)集中的,哪么該表的數(shù)據(jù)將不會(huì)被刪除。你也可以明確的加入一個(gè)空的表元素,例如<MY_TABLE/>(可以達(dá)到刪除 測(cè)試數(shù)據(jù)庫表中內(nèi)容的作用),如果要明確指定一個(gè)空的值,那么使用值[null]。

             為UserDAOTest我們創(chuàng)建一個(gè)數(shù)據(jù)集,并放在UserDAOTest.class文件同目錄下。

          <?xml version='1.0' encoding='UTF-8'?>

          <dataset>

              <usergroup name="admin" />  

              <user userName="jdoe"  name="doe"   firstname="john"   userGroup="admin" />

              <usergroup name="sales" />    

              <user userName="smith" name="smith" userGroup="sales" />

              

          </dataset>

             測(cè)試運(yùn)行的時(shí)候,首先將刪除掉usergroup表和user表中的所有內(nèi)容,然后將插入數(shù)據(jù)集中的內(nèi)容。其中name為smith的firstname的值將會(huì)是null。

             假設(shè)testFindByMinimalAge()方法將使用一個(gè)特殊的數(shù)據(jù)集而不是使用class級(jí)別的數(shù)據(jù)集,你可以定義一個(gè)UserDAOTest.testFindByMinimalAge.xml 數(shù)據(jù)集文件并放在測(cè)試類的class文件同目錄下。

          <?xml version='1.0' encoding='UTF-8'?>

          <dataset>

              <user userName="jack" age="18" />

              <user userName="jim"  age="17" />

          </dataset>

          這時(shí),你在testFindByMinimalAge()方法使用@DataSet注解,他將覆蓋class級(jí)的數(shù)據(jù)集

          public class UserDAOTest extends UnitilsJUnit4 {

          @Test

          @DataSet("UserDAOTest.testFindByMinimalAge.xml")

          public void testFindByMinimalAge() {

          List<User> result = userDao.findByMinimalAge(18); 

          assertPropertyLenEquals("firstName", Arrays.asList("jack"), result);

          }

          }

          不要過多的使用method級(jí)的數(shù)據(jù)集,因?yàn)檫^多的數(shù)據(jù)集文件意味著你要花大量的時(shí)間去維護(hù),你優(yōu)先考慮的是使用class級(jí)的數(shù)據(jù)集。

          配置數(shù)據(jù)集加載策略

          缺省情況下數(shù)據(jù)集被寫入數(shù)據(jù)庫采用的是clean insert策略。這就意味著數(shù)據(jù)在被寫入數(shù)據(jù)庫的時(shí)候是會(huì)先刪除數(shù)據(jù)集中有使用的表的數(shù)據(jù),然后在將數(shù)據(jù)集中的數(shù)據(jù)寫入數(shù)據(jù)庫。加載策略是可配額制的,我們通過修改DbUnitModule.DataSet.loadStrategy.default 的屬性值來改變加載策略。假設(shè)我們?cè)趗nitils.properties屬性文件中加入以下內(nèi)容:

          DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.InsertLoadStrategy 

          這時(shí)加載策略就由clean insert變成了insert,數(shù)據(jù)已經(jīng)存在表中將不會(huì)被刪除,測(cè)試數(shù)據(jù)只是進(jìn)行插入操作。

          加載策略也可以使用@DataSet的注解屬性對(duì)單獨(dú)的一些測(cè)試進(jìn)行配置:

          @DataSet(loadStrategy = InsertLoadStrategy.class) 

          對(duì)于那些樹形DbUnit的人來說,配置加載策略實(shí)際上就是使用不同的DatabaseOperation,以下是默認(rèn)支持的加載策略方式:

          CleanInsertLoadStrategy: 先刪除dateSet中有關(guān)表的數(shù)據(jù),然后再插入數(shù)據(jù)。

          InsertLoadStrategy: 只插入數(shù)據(jù)。

          RefreshLoadStrategy: 有同樣key的數(shù)據(jù)更新,沒有的插入。

          UpdateLoadStrategy: 有同樣key的數(shù)據(jù)更新,沒有的不做任何操作。

          配置數(shù)據(jù)集工廠

           在Unitils中數(shù)據(jù)集文件采用了multischema xml 格式,這是DbUnits的FlatXmlDataSet 格式的擴(kuò)展。配置文件格式和文件的擴(kuò)展可以采用DataSetFactory 。

          雖然Unitils當(dāng)前只支持一種數(shù)據(jù)格式,但是我們可以通過實(shí)現(xiàn)DataSetFactory來使用其他文件格式。當(dāng)你想使用excel而不是xml格式的時(shí)候,可以通過unitils.property中的DbUnitModule.DataSet.factory.default 屬性和@DataSet 注解來創(chuàng)建一個(gè)DbUnit's XlsDataSet 實(shí)例。

          驗(yàn)證測(cè)試結(jié)果

          有些時(shí)候我們想在測(cè)試時(shí)完畢后使用數(shù)據(jù)集來檢查數(shù)據(jù)庫中的內(nèi)容,舉個(gè)例子當(dāng)執(zhí)行完畢一個(gè)存儲(chǔ)過程后你想檢查一下啊數(shù)據(jù)是否更新了沒有。

          下面的例子表示的是禁用到一年內(nèi)沒有使用過的帳戶

          public class UserDAOTest extends UnitilsJUnit4 { 

              @Test @ExpectedDataSet 

              public void testInactivateOldAccounts() { 

                  userDao.inactivateOldAccounts(); 

              } 

          注意在test方法上增加了一個(gè)@ExpectedDataSet 注解。這將指明unitils將使用UserDAOTest.testInactivateOldAccounts-result.xml 這個(gè)數(shù)據(jù)集的內(nèi)容和數(shù)據(jù)庫的內(nèi)容進(jìn)行比較。

          <?xml version='1.0' encoding='UTF-8'?> 

          <dataset> 

              <user userName="jack" active="true" /> 

              <user userName="jim"  active="false" /> 

          </dataset> 

          根據(jù)這個(gè)數(shù)據(jù)集,將會(huì)檢查是否有兩條和記錄集的值相同的記錄在數(shù)據(jù)庫中。而其他的記錄和表將不理會(huì)。

          使用的是@DataSet 注解的話,文件名可以明確指出,如果文件名沒有明確指出來,那么文件名將匹配className .methodName -result.xml 

          使用少使用結(jié)果數(shù)據(jù)集,加入新的數(shù)據(jù)集意味著更多的維護(hù)。替代方式是在代碼中執(zhí)行相同的檢查(如使用一個(gè)findactiveusers()方法)。

          使用多模式的數(shù)據(jù)集

          一個(gè)程序不單單只是連接一個(gè)數(shù)據(jù)庫shema。Unitils采用了擴(kuò)展的數(shù)據(jù)集xml來定義多schemas下的數(shù)據(jù)。以下就是一個(gè)讀取數(shù)據(jù)到2個(gè)不同的schemas中的例子:

          <?xml version='1.0' encoding='UTF-8'?> 

          <dataset xmlns="SCHEMA_A" xmlns:b="SCHEMA_B"> 

              <user id="1" userName="jack" />     

              <b:role id="1" roleName="admin" /> 

          </dataset> 

          在這個(gè)例子中我定義了兩個(gè)schemas,SCHEMA_A 和 SCHEMA_B第一個(gè)schema,SCHEMA_A 被連接到默認(rèn)的xml命名空間中,第二個(gè)schema,SCHEMA_B 被連接到命名空間b。如果表xml元素的前綴使用了命名空間b,那么該表就是schema SCHEMA_B 中的,如果沒有使用任何的命名空間那么該表將被認(rèn)為是SCHEMA_A  

          中的。以上例子中測(cè)試數(shù)據(jù)定義了表SCHEMA_A.user SCHEMA_B.role

          如果在數(shù)據(jù)集中沒有配置一個(gè)默認(rèn)的命名空間,那么將會(huì)采用在unitils.properties中的屬性database.schemaNames 的第一個(gè)值作為默認(rèn)的

          database.schemaNames=SCHEMA_A, SCHEMA_B 

          這個(gè)配置將SCHEMA_A 作為缺省的schema,這樣你可以簡化數(shù)據(jù)集的聲明。

          <?xml version='1.0' encoding='UTF-8'?> 

          <dataset xmlns:b="SCHEMA_B"> 

              <user id="1" userName="jack" />     

              <b:role id="1" roleName="admin" /> 

          </dataset> 

          連接測(cè)試數(shù)據(jù)庫 

          在以上所有的例子中,我們都有一件重要的事情沒有做:當(dāng)我們進(jìn)行測(cè)試的時(shí)候,怎樣連接數(shù)據(jù)庫并得到DataSource?

          當(dāng)測(cè)試套件的第一個(gè)測(cè)試數(shù)據(jù)庫的案例運(yùn)行的時(shí)候,Unitils將會(huì)通過屬性文件創(chuàng)建一個(gè)DataSource 的實(shí)例來連接你單元測(cè)試時(shí)的數(shù)據(jù)庫,以后的測(cè)試中都將使用這個(gè)DataSource 實(shí)例。連接配置的詳細(xì)內(nèi)容如下:

          database.driverClassName=oracle.jdbc.driver.OracleDriver 

          database.url=jdbc:oracle:thin:@yourmachine:1521:YOUR_DB 

          database.userName=john 

          database.password=secret 

          database.schemaNames=test_john 

          配置章節(jié)所說的那樣,你可以將連接數(shù)據(jù)庫的驅(qū)動(dòng)類和url地址配置到unitils.properties 中去,而用戶名,密碼以及schema可以配置到unitils-local.properties 中去,這樣可以讓開發(fā)人員連接到自己的單元測(cè)試數(shù)據(jù)庫中進(jìn)行測(cè)試而不會(huì)干預(yù)到其他的人。

          在屬性或者setter方法前使用注解@TestDataSource ,將會(huì)將DataSource 實(shí)例注入到測(cè)試實(shí)例中去,如果你想加入一些代碼或者配置一下你的datasource,你可以做一個(gè)抽象類來實(shí)現(xiàn)該功能,所有的測(cè)試類都繼承該類。一個(gè)簡單的例子如下:

          public abstract class BaseDAOTest extends UnitilsJUnit4 { 

              @TestDataSource 

              private DataSource dataSource; 

               

              @Before     

              public void initializeDao() { 

                  BaseDAO dao = getDaoUnderTest(); 

                  dao.setDataSource(dataSource); 

              } 

              protected abstract BaseDAO getDaoUnderTest(); 

          上面的例子采用了注解來取得一個(gè)datasource的引用,另外一種方式就是使用DatabaseUnitils.getDataSource() 方法來取得datasource。

          事務(wù)

          出于不同的原因,我們的測(cè)試都是運(yùn)行在一個(gè)事務(wù)中的,其中最重要的原因如下:

          數(shù)據(jù)庫的很多action都是在事務(wù)正常提交后才做,如SELECT FOR UPDATE 和觸發(fā)器

          許多項(xiàng)目在測(cè)試數(shù)據(jù)的時(shí)候都會(huì)填寫一些測(cè)試數(shù)據(jù),每個(gè)測(cè)試運(yùn)行都會(huì)修改或者更新了數(shù)據(jù),當(dāng)下一個(gè)測(cè)試運(yùn)行的時(shí)候,都需要將數(shù)據(jù)回復(fù)到原有的狀態(tài)。

          如果使用的是hibernate或者JPA的時(shí)候,都需要每個(gè)測(cè)試都運(yùn)行在事務(wù)中,保證系統(tǒng)的正常工作。

          缺省情況下,事務(wù)管理是disabled的,事務(wù)的默認(rèn)行為我們可以通過屬性文件的配置加以改變:

          DatabaseModule.Transactional.value.default=commit 

          采用這個(gè)設(shè)置,每個(gè)的測(cè)試都將執(zhí)行commit,其他的屬性值還有rollback disabled 

          我們也可以通過在測(cè)試類上使用注解@Transactional 來改變默認(rèn)的事務(wù)設(shè)置,如:

          @Transactional(TransactionMode.ROLLBACK) 

          public class UserDaoTest extends UnitilsJUnit4 { 

          通過這種class上注解的事務(wù)管理,可以讓每個(gè)測(cè)試都確保回滾,@Transactional 注解還可以繼承的,因此我們可以將其放在父類中,而不必每個(gè)子類都進(jìn)行聲明。

          .........

          如果你使用Unitils的spring支持(見使用spring進(jìn)行測(cè)試)你如果配置了PlatformTransactionManager 的bean,那么unitils將會(huì)使用這個(gè)事務(wù)管理。

          posted @ 2008-08-25 15:11 小小~咖啡豆 閱讀(1950) | 評(píng)論 (2)編輯 收藏
          1、使用Dir:  
          If   Dir$(dirName,   ATTR_DIRECTORY)   =   ""   Then  
            'Directory   does   not   exist  
          Else  
            'Directory   does   exist  
          End   If  
          2、使用FileSystemObject:  
          Set   objFSO   =   CreateObject("Scripting.FileSystemObject")  
             
          If   objFSO.FolderExists(dirName)   Then  
            'Directory   does   exist  
          Else  
            'Directory   does   not   exist  
          End   If
          posted @ 2008-07-04 10:06 小小~咖啡豆 閱讀(678) | 評(píng)論 (0)編輯 收藏
          主站蜘蛛池模板: 潮安县| 金秀| 宜章县| 诸城市| 东台市| 沐川县| 阜阳市| 托里县| 额济纳旗| 绥滨县| 汕尾市| 抚顺县| 孝昌县| 巴青县| 八宿县| 得荣县| 延安市| 峨眉山市| 宜君县| 汝南县| 临邑县| 镇赉县| 滁州市| 湖州市| 合水县| 仙游县| 吉安市| 临江市| 新邵县| 灵石县| 郓城县| 海原县| 偃师市| 和田县| 新河县| 东宁县| 武宁县| 织金县| 延长县| 城固县| 襄汾县|