《Spring 3.0就這麼簡單》.(陳雄華,林開雄)第8章,對如何用Unitils進行測試簡單介紹,下面是我用Unitils進行單元測試過程中遇到的問題的總結。
1、設定好pom.xml依賴後,pom檔案報錯:Missing artifact javax.transaction:jta:jar:1.0.1B
原因是本地maven庫中缺少jta-1_0_1B-classes這個jar,需要把這個jar安裝到本地庫中去。
下載包含此jar的zip包,地址:http://download.csdn.net/detail/spring123tt/6847843
cmd到zip包的目錄,執行下面的字串
mvn install:install-file -Dfile=./jta-1_0_1B-classes.zip -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar
2、用Excel檔案作為驗證資料的輸入源,執行TestNG的時候報錯:
java.lang.NoClassDefFoundError: org/apache/poi/hssf/usermodel/HSSFWorkbook
Caused by: java.lang.ClassNotFoundException: org.apache.poi.hssf.usermodel.HSSFWorkbook
原因:java在操作Excel等Office檔案時,需要引入poi支援,所以需要在pom.xml中加入包依賴
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
3、執行TestNG報錯:
java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFDateUtil.isCellDateFormatted(Lorg/apache/poi/hssf/usermodel/HSSFCell;)
原因:dbunit對poi支援不夠好,詳見http://stamen.iteye.com/blog/1478022
更新dbunit版本到最新的2.5.1解決
4、執行TestNG報錯:
org.apache.commons.beanutils.ConversionException: No value specified for 'Date'
原因:beanutils用到了時間等非內建物件時,如果物件為NULL則,會出現此異常
我的這個測試用例的目的是將Excel中的多行資料插入到資料庫裡面去,很顯然,要插入的資料裡面Date型別出現了null值。
先在XlsDataSetBeanFactory.createbeans方法中把讀取到的資料逐行列印出來,看看到底哪些資料在搗鬼。我的Excel資料是這樣的:
而實際列印的資料卻出現了:
stu_netname:null
stu_password:null
stu_realname:null
stu_registdate:null
雖然Excel檔案中有幾行用看上去都是空白,但是實際上很可能是新增了空格在裡面,從而引起類似的錯誤,解決方法就是把Excel檔案中真實資料下面的幾行刪掉。
另外,通過google搜尋到了另外的解決方法,思路是遇到Null值得時候進行規避而不是報錯:http://www.blogjava.net/javagrass/archive/2011/10/10/352856.html
5、執行TestNG報錯:
org.dbunit.DatabaseUnitRuntimeException: At least one column is required to build a valid select statement
起因是新版本的dbunit細化了各種資料庫的MetadataHandler的處理,為每一種資料庫提供了一個MetadataHandler,如MySqlMetadataHandler,Db2MetadataHandler等。而unitils並沒有升級,仍然使用dbunit提供的DefaultMetadataHandler。這個DefaultMetadataHandler並不能很好的處理各個資料庫之間的不同,所以會導致相容問題。
解決方案:寫一個擴充類MySqlDbUnitModule繼承 DbUnitModule,
public
final
class
MySqlDbUnitModule
extends
DbUnitModule {
@Override
public
DbUnitDatabaseConnection getDbUnitDatabaseConnection(
final
String schemaName) {
DbUnitDatabaseConnection result = dbUnitDatabaseConnections.get(schemaName);
if
(
null
!= result) {
return
result;
}
result =
super
.getDbUnitDatabaseConnection(schemaName);
result.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
new
MySqlDataTypeFactory());
result.getConfig().setProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER,
new
MySqlMetadataHandler());
return
result;
}
}
使用新建的MySqlDbUnitModule替換預設的DbUnitModule。這個就比較簡單了,在unitils.properties中加入:
unitils.module.dbunit.className=com.miraclesea.test.database.module.MySqlDbUnitModule
該問題參考:http://my.oschina.net/u/719192/blog/173644
6、我的bean宣告採用,註解+自動掃描的方式:
<context:component-scan base-package="com.huawei.happycar.dao.impl,com.huawei.happycar.service.impl" />
我的業務裡面定義為:
@Service("studentServiceBean")
public class StudentServiceImpl implements StudentService {}
對studentServieBean,TestNG執行的時候就會報錯(意思是找不到這個bean):
Unable to assign the Spring bean value to field annotated with @SpringBean
Unable to assign the value to field: studentServiceImpl. Ensure that this field is of the correct type. Value: com.huawei.happycar.service.impl.StudentServiceImp
如果我定義為:
@Service("studentServiceBean")
public class StudentServiceImpl {}
對studentServieBean,TestNG執行的時候沒有一點問題。
另外,如果我用Junit的方法測試,兩種方法都沒有問題,該問題我還沒有解決,懷疑是Unitils的bug
使用Excel作為資料來源進行Unitils測試時,要注意的問題
1、unitils配置檔案的設定中如下兩項要按照實際的路徑進行修改
DbUnitModule.DataSet.factory.default=com.huawei.happycartest.dataset.excel.MultiSchemaXlsDataSetFactory
DbUnitModule.ExpectedDataSet.factory.default=com.huawei.happycartest.dataset.excel.MultiSchemaXlsDataSetFactory
2、測試方法
public class StudentDaoTest extends BaseDaoTest { @SpringBean("StudentDaoImpl") private StudentDaoImpl StudentDaoImpl; @Test @ExpectedDataSet("StudentDao.SaveStudents.xls") public void saveUsers()throws Exception { List<Student> users = XlsDataSetBeanFactory.createBeans(StudentDaoTest.class,"StudentDao.SaveStudents.xls", "t_student", Student.class); for(Student u:users){ StudentDaoImpl.save(u); } } }
上面的寫法中StdentDao.SaveStudents.xml一定要和StudentDaoTest.class在一個目錄下。
使用Junit方法的測試
@Test public void test() { ApplicationContext ac = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml", "spring-hibernate.xml" }); // 從Spring的IOC容器中獲取bean物件 StudentService userService = (StudentService) ac.getBean("studentServiceBean"); // 執行測試方法 List<Student> list = userService.listAllStudent(); for(Student stu : list) { System.out.println(stu.getStuNetname()); } }
這個Unitils測試框架官網上維護更新非常慢,Unitils的官方最新版本是3.3,對應的釋出時間是2011年12月22號。
所以顯然它不能支援Hibernate4了,另外就是Spring4估計也不是完美。
支援決定放棄使用這個測試框架,學習一下spring test。