1. 程式人生 > >Spring Test 整合 JUnit 4 使用總結

Spring Test 整合 JUnit 4 使用總結

               

這兩天做Web開發,發現通過Spring進行物件管理之後,做測試變得複雜了。因為所有的Bean都需要在applicationContext.xml中載入好,之後再通過@Resource去取得。如果每次都要整個業務流做的差不多了再去測試,這樣效率很低,也很麻煩。如果單獨去寫一個測試用類,這樣太繁瑣了。於是想起Spring有一個測試框架,能夠整合JUnit進行測試,於是便拿出來試試~

1. 加入依賴包

  使用Spring的測試框架需要加入以下依賴包

  • Spring Test (Spring框架中的test包)
  • Spring 相關其他依賴包(不再贅述了,就是context等包)

2. 建立測試源目錄和包

  在此,推薦建立一個和src平級的原始檔目錄,因為src內的類都是為日後產品準備的,而此處的類僅僅用於測試。而包的名稱可以和src中的目錄同名,這樣由於在test源目錄中,所以不會有衝突,而且名稱又一模一樣,更方便檢索。

3. 建立測試類

  建立一個測試用的類,推薦名稱為 “被測試類名稱 + Test”。

  測試類應該繼承與 AbstractJUnit4SpringContextTests 或 AbstractTransactionalJUnit4SpringContextTests

  對於 AbstractJUnit4springcontextTests 和 AbstractTransactionalJUnit4SpringContextTests 類的選擇:

  如果再你的測試類中,需要用到事務管理(比如要在測試結果出來之後回滾測試內容),就可以使用AbstractTransactionalJUnit4SpringTests類

。事務管理的使用方法和正常使用Spring事務管理是一樣的。再此需要注意的是,如果想要使用宣告式事務管理,即使用AbstractTransactionalJUnitSpringContextTests類,請在applicationContext.xml檔案中加入transactionManager bean:

<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="dataSource" /></bean>

 如果沒有新增上述bean,將會丟擲NoSuchBeanDefinitionException,指明 No bean named 'transactionManager' is definded.

4. 配置測試類

  新增如下內容在class前,用於配置applicationContext.xml檔案的位置。

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:applicationContext.xml")

5. 建立測試方法

  建立測試用方法,推薦名稱為 “被測方法名稱+ Test”。

  測試方法上方加入 @Test

6. 通過JUnit 4 執行

  右鍵方法名,選擇則“Run As”→“JUnit Test”即可

附錄1:整體測試類檔案

複製程式碼
/* @(#) UserDaoTest.java * */package com.phj.dao;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.phj.entity.User;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:applicationContext.xml")public class UserDaoTest extends AbstractJUnit4SpringContextTests {    @Resourceprivate UserDaoInterface userDao;    @Testpublic void saveTest() {        User user1 = new User();        user1.setUsername("tom");        user1.setPassword("123456");        user1.setNickName("tom");        user1.setEmail("[email protected]");        User user2 = new User();        user2.setUsername("admin");        user2.setPassword("123456");        user2.setNickName("admin");        user2.setEmail("[email protected]");        User user3 = new User();        user3.setUsername("feihong");        user3.setPassword("123456");        user3.setNickName("phj");        user3.setEmail("[email protected]");        userDao.save(user1);        userDao.save(user2);        userDao.save(user3);    }}

  OK,到此為止就可以使用Spring的測試框架了。

使用註解時,Junit報錯:

  1. java.lang.NoSuchFieldError: NULL  
  2.     at org.junit.runners.ParentRunner.<init>(ParentRunner.java:48)  
  3.     at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:59)  
  4.     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:104)  
  5.     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)  
  6.     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)  
  7.     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)  
  8.     at java.lang.reflect.Constructor.newInstance(Constructor.java:513)  
  9.     at org.junit.internal.requests.ClassRequest.buildRunner(ClassRequest.java:33)  
  10.     at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:28)  
  11.     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:28)  

經檢查是jar包衝突,我在建專案的時候,myeclipse有自動加入junit4,而後面我又自己加入Junit4.8.1。

如果報以下錯誤,則是junit包版本太低,需要4.5或以上的版本

  1. Caused by: java.lang.ClassNotFoundException: org.junit.runners.BlockJUnit4ClassRunner    
  2.     at java.net.URLClassLoader$1.run(URLClassLoader.java:200)    
  3.     at java.security.AccessController.doPrivileged(Native Method)    
  4.     at java.net.URLClassLoader.findClass(URLClassLoader.java:188)    
  5.     at java.lang.ClassLoader.loadClass(ClassLoader.java:307)    
  6.     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)    
  7.     at java.lang.ClassLoader.loadClass(ClassLoader.java:252)    
  8.     at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)  

其他問題:

@ContextConfiguration({"classpath:applicationContext.xml","classpath:spring/buyer/applicationContext-service.xml"})匯入配置檔案,這裡我的applicationContext配置檔案是根據模組來分類的。如果有多個模組就引入多個“applicationContext-service.xml”檔案。如果所有的都是寫在“applicationContext。xml”中則這樣匯入: @ContextConfiguration(locations = "classpath:applicationContext.xml")@RunWith(SpringJUnit4ClassRunner.class)SpringJUnit支援,由此引入Spring-Test框架支援! @Transactional這個非常關鍵,如果不加入這個註解配置,事務控制就會完全失效! @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)這裡的事務關聯到配置檔案中的事務控制器(transactionManager = "transactionManager"),同時指定自動回滾(defaultRollback = true)。這樣做操作的資料才不會汙染資料庫! AbstractTransactionalDataSourceSpringContextTests要想構建這一系列的無汙染純綠色事務測試框架就必須找到這個基類!(即所有事務均不生效)

import com.wonders.frame.ias.service.IasScheduleTask;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.stereotype.Component;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;/** * Created with IntelliJ IDEA. * User: zhoushun * Date: 2015/3/30 * Time: 12:40 * To change this template use File | Settings | File Templates. */@Component@Transactional@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath*:applicationContext.xml")//public class IasTest extends AbstractTransactionalJUnit4SpringContextTests{public class IasTest extends AbstractJUnit4SpringContextTests {    @Resource    private IasScheduleTask task;    @Test    public void taskTest(){        task.urgeTask();    }}