<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    邊城愚人

    如果我不在邊城,我一定是在前往邊城的路上。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      31 隨筆 :: 0 文章 :: 96 評論 :: 0 Trackbacks

    ??? ??? 做 java 企業級開發時,我們通常采用三層架構。特別地,如果我們要做的系統的業務邏輯不是很復雜時,我們要處理的不過是 CRUD 操作,這時我們可能將 dao 層與 service 層合并為一層,盡管很多人會這樣做,但我仍傾向于將兩層分開;因為 service dao 不是一一對應的,從復用及邏輯清晰的角度考慮,應該將它們分開。在三層架構下,對于 web 層, service 層, dao 層我們都該怎么測試?這里我將介紹基于 Spring Hibernate DbUnit 的情況下我的測試方法。由于使用了 Spring ,事務管理就不在 dao ,因此要單獨地測試 dao 可能要麻煩一些;另一方面, dao 中的操作大多是簡單的,也不是很值得測試。在使用了 Hibernate Spring 的情況下,我們要測試的除了 HQL ,還有其配置文件,我覺得對數據持久化的測試最好定在 service 上。如果 service 業務邏輯復雜的話,與數據持久化無關的業務邏輯(應該寫在領域對象中)可以單獨測試 ,在保證與數據持久化無關的業務邏輯的正確性下,帶上 dao 操作做集成(單元)測試。

    ??? ??

    在使用 Spring 做測試時,推薦測試類繼承自 Spring AbstractTransactionalDataSourceSpringContextTests ,這也是官方推薦的做法。 AbstractTransactionalDataSourceSpringContextTests 對測試方法提供了事務管理,同時它的依賴注入特性也方便測試類注入被測試類(但我并不認為它的事務管理是很需要的)。承接于上一篇文章中的例子 ,下面給出測試類 AccountServiceTest。


    package ?hibernatesample.service;
    import ?hibernatesample.domain.Account;
    import ?java.io.File;
    import ?java.io.InputStream;
    import ?java.util.List;
    import ?org.dbunit.IDatabaseTester;
    import ?org.dbunit.JdbcDatabaseTester;
    import ?org.dbunit.dataset.IDataSet;
    import ?org.dbunit.dataset.xml.FlatXmlDataSet;
    import ?org.springframework.test.AbstractDependencyInjectionSpringContextTests;
    import ?org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;

    public ? class ?AccountServiceTest? extends ?AbstractTransactionalDataSourceSpringContextTests?{

    ????
    private ?AccountService?accountService;
    ????
    private ?IDatabaseTester?databaseTester;

    ????
    public ?AccountService?getAccountService()?{
    ????????
    return ?accountService;
    ????}
    ????
    ????
    public ?AccountServiceTest() throws ?Exception{
    ????
    ????}

    ????
    public ? void ?setAccountService(AccountService?accountService)?{
    ????????
    this .accountService? = ?accountService;
    ????}

    ????@Override
    ????
    protected ? void ?onSetUp()? throws ?Exception?{
    ????????databaseTester?
    = ? new ?JdbcDatabaseTester( " com.mysql.jdbc.Driver " ,
    ????????????????
    " jdbc:mysql://localhost/HibernateSample " ,? " root " ,? " 0102 " );
    ?????IDataSet?dataSet?
    = ?getDataSet();
    ?????databaseTester.setDataSet(?dataSet?);
    ?????databaseTester.onSetup();
    ????}

    ????@Override
    ????
    protected ? void ?onTearDown()? throws ?Exception?{
    ????????databaseTester.onTearDown();
    ????}

    ????
    protected ?IDataSet?getDataSet()? throws ?Exception?{
    ????????String?path?
    = ? " hibernatesample " + File.separator + " dao " + File.separator + " dataset " + File.separator + " Account.xml " ;
    ????????InputStream?in?
    = ? this .getClass().getClassLoader().getResourceAsStream(path);
    ????????
    return ? new ?FlatXmlDataSet(in);
    ????}
    ????

    ????@Override
    ????
    protected ?String[]?getConfigLocations()?{
    ????????
    ????????
    return ? new ?String[]{ " classpath:service-applicationContext.xml " };
    ????}
    ????
    ????
    public ? void ?testInsert()?{
    ????????Account?a?
    = ? new ?Account();
    ????????a.setName(
    " aa " );
    ????????accountService.insertAccount(a);
    ????????List
    < Account > ?l? = ?accountService.findAllAccount();
    ????????assertEquals(
    3 ,?l.size());
    ????????Account?b?
    = ?l.get( 2 );
    ????????assertEquals(
    " aa " ,?b.getName());
    ????}

    ????
    public ? void ?testFindAll()?{
    ????????List
    < Account > ?l? = ?accountService.findAllAccount();
    ????????assertEquals(
    2 ,?l.size());
    ????????Account?a?
    = ?l.get( 0 );
    ????????assertEquals(
    new ?Long( 1 ),?a.getId());
    ????????assertEquals(
    " kafka " ,?a.getName());
    ????????Account?b?
    = ?l.get( 1 );
    ????????assertEquals(
    new ?Long( 2 ),?b.getId());
    ????????assertEquals(
    " 0102 " ,?b.getName());
    ????}
    }

    ??? ??? 由于 AccountServiceTest 繼承了 AbstractTransactionalDataSourceSpringContextTests ,因此使用 D b Unit 時就不能繼承 DBTestCase ,這里采用的方法就是在 onSetUp() 中實現數據集的裝入。由于 AbstractTransactionalDataSourceSpringContextTests 最第 N 個頂層的父類繼承于 Junit ,所以 onSetUp() 將在 SetUp() 中被調用,默認的 onSetUp() 實現為空; onTearDown() 的原理和 onSetUp() 相似。由于 AbstractTransactionalDataSourceSpringContextTests 具有依賴注入的特性,所以被測試對象 accountService 可以通過 setter 方法獲得;當然,我們也可以在構造函數中通過 Bean 工廠獲得 accountService protected String[] getConfigLocations() 返回的數組為 Spring Beans 配置文件的位置。

    ??? ??? 對于與測試相關的其他類,這里就不給出了。通過使用 DbUnit ,我覺得測試持久化操作時方便了許多。不爽的地方在于,在使用了 Spring Hibernate 的情況下,測試一個方法有些耗時,這自然不單單是 DbUnit 的問題。但如果我將 dao service 的測試放在一起來做,這種耗時也只能忍著。再說一下 web 層的測試,我當前使用的 web 框架是 Webwork ,在測試 Action 的時候,對于 Web 請求之類使用 Mock ,對于 Service 的調用有時 Mock 有時真實調用。 Mock 的好處是耗時能少一些,但寫 Mock 代碼也很繁瑣,而對 service Mock 有時本身就失掉了測試的意義。

    posted on 2007-06-14 09:18 kafka0102 閱讀(1480) 評論(0)  編輯  收藏 所屬分類: TDD

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: japanese色国产在线看免费| 亚洲国产精品久久久久秋霞影院 | 拍拍拍无挡免费视频网站| 色视频色露露永久免费观看| 亚洲一区AV无码少妇电影| 久久这里只有精品国产免费10| 99久久99热精品免费观看国产 | 国产天堂亚洲精品| 日韩免费高清视频网站| 亚洲人成精品久久久久| 国产一区二区免费| 老司机亚洲精品影院| 18勿入网站免费永久| 亚洲日本天堂在线| 免费a级毛片在线观看| 无码毛片一区二区三区视频免费播放| 国产jizzjizz免费看jizz| 国产黄色片免费看| 亚洲av无码成h人动漫无遮挡 | 无码人妻一区二区三区免费视频 | 一级女性全黄久久生活片免费| 亚洲日韩一页精品发布| 免费播放一区二区三区| 亚洲五月丁香综合视频| 免费在线看片网站| 嫩草在线视频www免费看| 91亚洲性爱在线视频| 免费吃奶摸下激烈视频| 四虎影视成人永久免费观看视频 | 99久久精品免费精品国产| 最新国产成人亚洲精品影院| 国产zzjjzzjj视频全免费| av永久免费网站在线观看| 亚洲youjizz| 无码人妻一区二区三区免费看| 亚洲免费观看在线视频| yy6080久久亚洲精品| 外国成人网在线观看免费视频| 亚洲av无码专区在线观看下载| 亚洲综合色婷婷七月丁香| 免费观看黄网站在线播放|