qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問 http://qaseven.github.io/

          持續(xù)集成之路——數(shù)據(jù)訪問層的單元測(cè)試(續(xù))

          在上一篇中,完成了對(duì)測(cè)試用數(shù)據(jù)源的配置。下面繼續(xù)構(gòu)建可運(yùn)行的測(cè)試。

            三、使用DBUnit管理數(shù)據(jù)

            測(cè)試的維護(hù)一直是我比較頭疼的問題,期望可以有一個(gè)比較易于維護(hù)和可復(fù)用的方法來管理這些數(shù)據(jù)。在沒有更好的方法之前,暫時(shí)選用DBUnit。(反思:其實(shí)我一直在為沒有發(fā)生的事情擔(dān)心,使得事情根本沒有進(jìn)展。從已存在的、最簡(jiǎn)單的地方入手,才是正確的處理方式。)

            在pom.xml中引入dbunit和springtestdbunit包,后者提供通過注解方式使用DBUnit:

          <dependency>
          <groupId>org.dbunit</groupId>
          <artifactId>dbunit</artifactId>
          <version>2.4.9</version>
          <scope>test</scope>
          </dependency>
          <dependency>
          <groupId>com.github.springtestdbunit</groupId>
          <artifactId>spring-test-dbunit</artifactId>
          <version>1.0.1</version>
          <scope>test</scope>
          </dependency>

            DBUnit使用xml文件管理數(shù)據(jù)集,通過使用第三方的庫也可以很方便的支持JSON格式。這里使用xml:

          <xml version="1.0" encoding="utf-8"?>
          <dataset>
              <building id="1" name="SOHO"/>
              <building id="2" name="New Gate Plaza"/>
              <floor id="1" floor_num="2" building="1"/>
              <floor id="2" floor_num="3" building="1"/>
              <floor id="3" floor_num="5" building="2"/>
          </dataset>

            這個(gè)數(shù)據(jù)文件放在了 /src/test/resources/中,與測(cè)試用例在同一個(gè)級(jí)別的目錄中。為了便于區(qū)分,我采用了:Dao類名-被測(cè)試的方法名-dataset.xml 的命名方式,例如:UserDao-findByname-dataxml.set。以后如果測(cè)試用例需要修改,就可以根據(jù)名字很方便地找到對(duì)應(yīng)的數(shù)據(jù)集,并且不會(huì)影響其他測(cè)試用例。

            注意:

            1. 這里的Element及其Attribute名稱要和數(shù)據(jù)庫的結(jié)構(gòu)一一對(duì)應(yīng),而不是實(shí)體類。

            2. 如果同一個(gè)數(shù)據(jù)對(duì)象初始化時(shí),需要初始化的字段數(shù)目不一樣,比如:一條數(shù)據(jù)需要初始化的字段是8個(gè),而另外一個(gè)是4個(gè)。那么一定要字段數(shù)多的放在前面。

            四、編寫測(cè)試用例

            在編寫用例前,還是看下被測(cè)試的代碼。用到的兩個(gè)實(shí)體類:

          package com.noyaxe.myapp.entity;

          import javax.persistence.Entity;
          import javax.persistence.Table;

          @Entity
          @Table(name = "building")
          public class Building extends IdEntity {
              private String name;


              public String getName() {
                  return name;
              }

              public void setName(String name) {
                  this.name = name;
              }
          }


          package com.noyaxe.myapp.entity;

          import javax.persistence.Column;
          import javax.persistence.Entity;
          import javax.persistence.JoinColumn;
          import javax.persistence.ManyToOne;
          import javax.persistence.Table;

          @Entity
          @Table(name = "floor")
          public class Floor extends IdEntity {
              private Integer floorNum;
              private Building building;

              @Column(name = "floor_num")
              public Integer getFloorNum() {
                  return floorNum;
              }

              public void setFloorNum(Integer floorNum) {
                  this.floorNum = floorNum;
              }

              @ManyToOne(optional = false)
              @JoinColumn(name = "building")
              public Building getBuilding() {
                  return building;
              }

              public void setBuilding(Building building) {
                  this.building = building;
              }
          }

            被測(cè)試的FloorDao:

          package com.noyaxe.myapp.repository;

          import com.noyaxe.myapp.entity.Floor;
          import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
          import org.springframework.data.repository.PagingAndSortingRepository;

          import java.util.List;

          public interface FloorDao extends JpaSpecificationExecutor<Floor>, PagingAndSortingRepository<Floor, Long> {
              public Floor findByBuildingNameAndFloorNum(String building, Integer floorNum);

              public List<Floor> findByBuildingName(String building);
          }



           測(cè)試用例也十分簡(jiǎn)單:

          package com.noyaxe.myapp.repository;

          import com.github.springtestdbunit.annotation.DatabaseSetup;
          import com.noyaxe.myapp.entity.Floor;
          import org.junit.Test;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
          import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
          import org.springframework.test.context.support.DirtiesContextTestExecutionListener;

          import java.util.List;

          import static junit.framework.Assert.assertNull;
          import static org.junit.Assert.assertEquals;
          import static org.junit.Assert.assertNotNull;

          @RunWith(SpringJUnit4ClassRunner.class)
          @ContextConfiguration("classpath:applicationContext-test.xml")
          @TestExecutionListeners({
          &nbsp; &nbsp; &nbsp; &nbsp; DependencyInjectionTestExecutionListener.class,
          &nbsp; &nbsp; &nbsp; &nbsp; DirtiesContextTestExecutionListener.class,
          &nbsp; &nbsp; &nbsp; &nbsp; TransactionDbUnitTestExecutionListener.class})
          public class FloorDaoTest {
              @Autowired
              private FloorDao floorDao;

              @Test
          <PRE class=java name="code">    @DatabaseSetup("FloorDao-findbByBuidlingName-dataset.xml")</PRE>    public void testFindByBuildingName(){        List<Floor> singleFloorList = floorDao.findByBuildingName("SOHO");        assertEquals(1, singleFloorList.size());        List<Floor> twoFloorList = floorDao.findByBuildingName("New Gate Plaza");        assertEquals(2, twoFloorList.size());        List<Floor> emptyFloorList = floorDao.findByBuildingName("Test");        assertEquals(0, emptyFloorList.size());    }    @Test<BR><PRE class=java name="code">    @DatabaseSetup("FloorDao-findbByBuidlingNameAndFloorNum-dataset.xml")</PRE>    public void testFindByBuildingNameAndFloorNum(){        Floor floor = floorDao.findByBuildingNameAndFloorNum("SOHO", 2);        assertNotNull(floor);        Floor empty = floorDao.findByBuildingNameAndFloorNum("New Gate Plaza", 7);        assertNull(empty);        empty = floorDao.findByBuildingNameAndFloorNum("No Building", 7);        assertNull(empty);    }}

            通過代碼,可以很清楚的看到通過DatabaseSetup完成了對(duì)測(cè)試數(shù)據(jù)的引入。這里在每個(gè)測(cè)試方法前引入不同的文件,如果所有的方法可以通過一個(gè)文件包括,那么也可以在類前面使用DatabaseSetup引入數(shù)據(jù)文件。

            至此,一個(gè)完整的數(shù)據(jù)層測(cè)試用例已經(jīng)呈現(xiàn),并且可以運(yùn)行。可是實(shí)際的過程卻并沒有這么順利,接下來的文章就要總結(jié)一下遇到的問題。

          相關(guān)文章:

          持續(xù)集成之路——數(shù)據(jù)訪問層的單元測(cè)試

          posted on 2013-07-25 10:45 順其自然EVO 閱讀(264) 評(píng)論(0)  編輯  收藏 所屬分類: 測(cè)試學(xué)習(xí)專欄

          <2013年7月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 页游| 丹寨县| 金湖县| 临汾市| 阳信县| 东兴市| 盐山县| 都安| 金昌市| 安仁县| 会理县| 古田县| 嫩江县| 岐山县| 江达县| 长阳| 清流县| 垫江县| 哈巴河县| 水城县| 永寿县| 崇文区| 青浦区| 三台县| 湘西| 呈贡县| 科技| 黑山县| 宝清县| 隆化县| 湘西| 炉霍县| 凯里市| 佳木斯市| 长海县| 博乐市| 民乐县| 潮州市| 阿鲁科尔沁旗| 眉山市| 台北市|