1. 程式人生 > >用Spring TestContext 做帶事務回滾的JUnit測試

用Spring TestContext 做帶事務回滾的JUnit測試

JUnit單元測試框架很常用 但可能會破壞資料庫現場 以及大量的硬編碼出現(applicationContext.getBean(""));

今天哥們給新手介紹一下 Spring Test這個Spring自帶的jar包中的一些註解 實現單元測試+事務回滾+註解依賴注入

網上的相關教程不多 我的意思是有用的不多 基本都是類似api文件那種 給你羅列一大堆註解和類 告訴你他們的作用 你看完了也不知道該從哪裡入手
我自己琢磨了幾天(哥們天賦不是很高) 寫了一個測試類 測試成功 給大家分享一下

首先匯入相關jar包和library 
jar包在Spring的lib下 Spring-test這個jar
然後匯入JUnit4的library 這個不用我教了吧。。。

然後再工程中新建一個src folder 起名為test
在test資料夾下建立一個包 暫定為com.test 建立一個類 普通的類即可
我起名為SchoolTest

這個SchoolTest類要繼承AbstractTransactionalJUnit4SpringTestContextTests 哥純粹是背下來的 畢竟以前當過翻譯 英文還湊合 不過背不下來也沒關係 其實很好理解 
Transactional代表事務的 其他幾個單詞其實不用解釋你也知道 多默寫幾遍就自然熟練了

接下來 在這個類上面加一個註解@RunWith(SpringJUnit4ClassRunner.class) 
RunWith是junit4的註解 意思是此類由這個註解的引數的類來主導單元測試 引數型別是Class
SpringJUnit4ClassRunner.class是SpringTest中的一個類 作用類似驅動 意思是由Spring Test來主導本次單元測試
然後在這個類上寫第二個註解
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
ContextConfiguration的作用是定位你的上下文配置檔案 作用就是減少硬編碼 getBean之類的
一旦開始測試 Spring 測試框架就去指定位置讀取配置檔案 完成依賴注入
引數是locations 注意有了s代表複數 引數的取值是字串陣列 所以引數要加{} 但如果引數只有一個 可以省略{} 但注意 只有在註解的引數型別是陣列且只有一個引數時 可以省略{}
別給我在普通java類裡來個String[] a="sb";這樣的



還有如果applicationContext.xml位於根目錄下 就一定要寫classpath: 否則會出錯
至於放在預設的WEB-INF下得情況 我沒試過是不是可以不寫locations 我也不想去試 沒必要
然後再寫第三個註解
@TestExecutionListeners(listeners={
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class
})
TestExecutionListener 顧名思義 測試執行監聽器 配置的是一系列監聽器 至於監聽器的作用本文暫時不提 自行百度
引數是listeners 同上 引數型別是Class陣列 裡面是各式各樣的監聽器 我選了兩個
一個是DependencyInjectionTestExecutionListener 監聽測試類中的依賴注入是否正確 不正確的話有什麼結果我也不知道 因為我每次都寫對的。。。
另一個是TransactionalTestExecutionListener 監聽測試類中的事務 如果測試類中涉及事務 就必須配這個監聽器

接下來寫第四個註解
@TransactionConfiguration(transactionManager="txManager",defaultRollback=true)
TransactionConfiguration 顧名思義 是配置事務情況的註解
第一個引數transactionManager是你在applicationContext.xml或bean.xml中定義的事務管理器的bean的id 
defaultRollback是個很關鍵的引數 是表示測試完成後事務是否會滾 引數是布林型的 預設就是true 但強烈建議寫上true
這是我的Spring配置檔案 大部分配置都是我手寫的 少部分是抄spring官方文件的 

下面在類中定義一個業務層的物件 或者叫屬性 成員變數 隨你

這個schoolBiz上面寫著@Resource 代表從配置檔案讀取一個叫做schoolBiz的bean 如果不用Spring託管單元測試 這個寫是無法完成注入的 因為沒有一個容器初始化配置檔案中的bean 在tomcat啟動時 tomcat會讀取這個配置檔案並初始化 但單元測試是與web容器相互獨立的 所以但用junit需要硬編碼 但有了spring test 就避免了硬編碼
下面 寫一個要測試的方法 加上兩個註解
一個是@Test 這個不多說了 Junit自帶的註解 表示要測試的方法
另一個是@Transactional 表示這個方法是事務的起始點 
注意的是 在業務層最好還是別用註解託管事務 因為每個方法都要這麼寫比較麻煩 用xml+spring表示式可以給所有方法託管事務

最後就是寫方法裡的邏輯了

現在開始測試
測試成功! 開啟資料庫 什麼也沒有 因為spring替你回滾了事務 保護了資料庫現場!
看資料庫表 什麼也沒有吧