Dict.CN 在線詞典, 英語學習, 在線翻譯

          都市淘沙者

          荔枝FM Everyone can be host

          統計

          留言簿(23)

          積分與排名

          優秀學習網站

          友情連接

          閱讀排行榜

          評論排行榜

          DbUnit入門實戰(轉載)

          相信做過單元測試的人都會對JUnit非常的熟悉了,今天要介紹的DbUnit(http://dbunit.sourceforge.net/)則是專門針對數據庫測試的對JUnit的一個擴展,它可以將測試對象數據庫置于一個測試輪回之間的狀態。鑒于目前國內介紹DbUnit的系統教程比較少見,本文將分從理論和實例兩個方面帶你領略DbUnit的精彩世界。
          DbUnit設計理念
          熟悉單元測試的開發人員都知道,在對數據庫進行單元測試時候,通常采用的方案有運用模擬對象(mock objects)和stubs兩種。通過隔離關聯的數據庫訪問類,比如JDBC的相關操作類,來達到對數據庫操作的模擬測試。然而某些特殊的系統,比如利用了EJB的CMP(container
          -managed persistence)的系統,數據庫的訪問對象是在最底層而且很隱蔽的,那么這兩種解決方案對這些系統就顯得力不從心了。
          DBUnit的設計理念就是在測試之前,備份數據庫,然后給對象數據庫植入我們需要的準備數據,最后,在測試完畢后,讀入備份數據庫,回溯到測試前的狀態;
          而且又因為DBUnit是對JUnit的一種擴展,開發人員可以通過創建測試用例代碼,在這些測試用例的生命周期內來對數據庫的操作結果進行比較。
          DbUnit測試基本概念和流程
          基于DbUnit 的測試的主要接口是IDataSet。IDataSet代表一個或多個表的數據。
          可以將數據庫模式的全部內容表示為單個IDataSet 實例。這些表本身由Itable 實例來表示。
          IDataSet 的實現有很多,每一個都對應一個不同的數據源或加載機制。最常用的幾種 IDataSet實現為:
          FlatXmlDataSet:數據的簡單平面文件 XML 表示
          QueryDataSet:用 SQL 查詢獲得的數據
          DatabaseDataSet:數據庫表本身內容的一種表示
          XlsDataSet :數據的excel表示
          一般而言,使用DbUnit進行單元測試的流程如下:
          1 根據業務,做好測試用的準備數據和預想結果數據,通常準備成xml格式文件。
          2 在setUp()方法里邊備份數據庫中的關聯表。
          3 在setUp()方法里邊讀入準備數據。
          4 對測試類的對應測試方法進行實裝:執行對象方法,把數據庫的實際執行結果和預想結果進行比較。
          5 在tearDown()方法里邊,把數據庫還原到測試前狀態。
          DbUnit開發實例
          下面通過一個實例來說明DbUnit的實際運用。
          實例準備
          比如有一個學生表[student],結構如下:

          --------------------------------------------------------------------------------
          id 
          char(4) pk 學號
          name 
          char(50) 姓名
          sex 
          char(1) 性別
          birthday date 出生日期
          --------------------------------------------------------------------------------
          準備數據如下:
          --------------------------------------------------------------------------------
          id name sex birthday
          0001 翁仔 m 1979-12-31
          0002 王翠花 f 1982-08-09
          --------------------------------------------------------------------------------
          測試對象類為StudentOpe.java,里邊有2個方法:
          findStudent(String id) :根據主鍵id找記錄
          addStudent(Student student) :添加一條記錄
          在測試addStudent方法時候,我們準備添加如下一條數據
          --------------------------------------------------------------------------------
          id name sex birthday
          0088 王耳朵 m 1982-01-01
          --------------------------------------------------------------------------------
          那么在執行該方法后,數據庫的student表里的數據是這樣的:
          --------------------------------------------------------------------------------
          id name sex birthday
          0001 翁仔 m 1979-12-31
          0002 王翠花 f 1982-08-09
          0088 王耳朵 m 1982-01-01
          --------------------------------------------------------------------------------
          然后我們說明如何對這2個方法進行單元測試。
          實例展開
          1 把準備數據和預想數據轉換成xml文件
          student_pre.xml

          --------------------------------------------------------------------------------
          <?xml version='1.0' encoding="gb2312"?>
          <dataset>
          <student id="0001" name="翁仔" sex="m" birthday="1979-12-31"/>
          <student id="0002" name="王翠花" sex="f" birthday="1982-08-09"/>
          </dataset>
          --------------------------------------------------------------------------------
          student_exp.xml
          --------------------------------------------------------------------------------
          <?xml version='1.0' encoding="gb2312"?>
          <dataset>
          <student id="0001" name="翁仔" sex="m" birthday="1979-12-31"/>
          <student id="0002" name="王翠花" sex="f" birthday="1982-08-09"/>
          <student id="0088" name="王耳朵" sex="m" birthday="1982-01-01"/>
          </dataset>
          --------------------------------------------------------------------------------
          2 實裝setUp方法,詳細見代碼注釋。

          --------------------------------------------------------------------------------
          protected void setUp() {
          IDatabaseConnection connection 
          =null;
          try{
          super.setUp();
          //本例使用postgresql數據庫
          Class.forName("org.postgresql.Driver");
          //連接DB
          Connection conn=DriverManager.getConnection("jdbc:postgresql:testdb.test","postgres","postgres");
          //獲得DB連接
          connection =new DatabaseConnection(conn);
          //對數據庫中的操作對象表student進行備份
          QueryDataSet backupDataSet = new QueryDataSet(connection);
          backupDataSet.addTable(
          "student");
          file
          =File.createTempFile("student_back",".xml");//備份文件
          FlatXmlDataSet.write(backupDataSet,new FileOutputStream(file));
          //準備數據的讀入
          IDataSet dataSet = new FlatXmlDataSet( new FileInputStream("student_pre.xml"));
          DatabaseOperation.CLEAN_INSERT.execute(connection,dataSet);
          }
          catch(Exception e){
          e.printStackTrace();
          }
          finally{
          try{
          if(connection!=null) connection.close();
          }
          catch(SQLException e){}
          }
          }
          --------------------------------------------------------------------------------
          3 實裝測試方法,詳細見代碼注釋。
          *檢索類方法,可以利用assertEquals()方法,拿表的字段進行比較。
          --------------------------------------------------------------------------------
          // findStudent
          public void testFindStudent() throws Exception{
          //執行findStudent方法
          StudentOpe studentOpe=new StudentOpe();
          Student result 
          = studentOpe.findStudent("0001");
          //預想結果和實際結果的比較
          assertEquals("翁仔",result.getName());
          assertEquals(
          "m",result.getSex());
          assertEquals(
          "1979-12-31",result.getBirthDay());
          }
          --------------------------------------------------------------------------------
          *更新,添加,刪除等方法,可以利用Assertion.assertEquals()方法,拿表的整體來比較。
          --------------------------------------------------------------------------------
          public void testAddStudent() throws Exception{
          //執行addStudent方法
          StudentOpe studentOpe=new StudentOpe();
          //被追加的記錄
          Student newStudent = new Student("0088","王耳朵","m","1982-01-01");
          //執行追加方法
          Student result = studentOpe.addStudent(newStudent);
          //預想結果和實際結果的比較
          IDatabaseConnection connection=null;
          try{
          //預期結果取得
          IDataSet expectedDataSet = new FlatXmlDataSet(new FileInputStream("student_exp.xml"));
          ITable expectedTable 
          = expectedDataSet.getTable("student");
          //實際結果取得
          Connection conn=getConnection();
          connection 
          =new DatabaseConnection(conn);
          IDataSet databaseDataSet 
          = connection.createDataSet();
          ITable actualTable 
          = databaseDataSet.getTable("student");
          //比較
          Assertion.assertEquals(expectedTable, actualTable);
          }
          finally{
          if(connection!=null) connection.close();
          }
          }
          --------------------------------------------------------------------------------
          *如果在整體比較表的時候,有個別字段不需要比較,可以用DefaultColumnFilter.excludedColumnsTable()方法,
          將指定字段給排除在比較范圍之外。比如上例中不需要比較birthday這個字段的話,那么可以如下代碼所示進行處理:
          --------------------------------------------------------------------------------
          ITable filteredExpectedTable 
          = DefaultColumnFilter.excludedColumnsTable(expectedTable, new String[]{"birthday"});
          ITable filteredActualTable 
          = DefaultColumnFilter.excludedColumnsTable(actualTable,new String[]{"birthday"});
          Assertion.assertEquals(filteredExpectedTable, filteredActualTable);
          --------------------------------------------------------------------------------
          4 在tearDown()方法里邊,把數據庫還原到測試前狀態
          --------------------------------------------------------------------------------
          protected void tearDown() throws Exception{
          IDatabaseConnection connection 
          =null;
          try{
          super.tearDown();
          Connection conn
          =getConnection();
          connection 
          =new DatabaseConnection(conn);
          IDataSet dataSet 
          = new FlatXmlDataSet(file);
          DatabaseOperation.CLEAN_INSERT.execute(connection,dataSet);
          }
          catch(Exception e){
          e.printStackTrace();
          }
          finally{
          try{
          if(connection!=null) connection.close();
          }
          catch(SQLException e){}
          }
          }

          posted on 2010-10-09 14:20 都市淘沙者 閱讀(320) 評論(0)  編輯  收藏 所屬分類: Hibernate/ORM

          主站蜘蛛池模板: 聂拉木县| 永康市| 石河子市| 汨罗市| 东安县| 靖宇县| 淅川县| 威宁| 额尔古纳市| 酉阳| 安乡县| 南溪县| 汕头市| 阿合奇县| 兰溪市| 新建县| 岢岚县| 伊金霍洛旗| 平原县| 长泰县| 河间市| 广南县| 樟树市| 吴桥县| 武汉市| 红原县| 海阳市| 宜川县| 肥东县| 海伦市| 金堂县| 阿克| 辉南县| 明溪县| 甘泉县| 太保市| 青浦区| 威海市| 巩留县| 体育| 梧州市|