Spring+hibernate+junit的Dao测试

来源:互联网 发布:flipchart软件下载 编辑:程序博客网 时间:2024/09/21 09:18

开发一个eclipse3.4+Struts2.0+hibernate3.2+Spring2.5+oracle10g的项目。实现完DAO层后,想对Dao层做下测试。以前都是用的Junit3.8,这次换了最新的Junit4.4,但是在写测试类时遇到不少麻烦,将碰到的问题和解决方法记录下来,供后来的朋友们参考。


下面分别讲解在Junit4.4和Junit3.8下如何写测试类。
对于Junit3.8:
Spring的DAO层的测试,spring-test.jar包里有个AbstractTransactionalDataSourceSpringContextTests类,只要继承它,然后重写getConfigLocations方法就可以了。比较简单,而且又支持回滚,没有数据库的耗时操作。
对于你所有的applicationContext.xml等spring配置文件,你都不用动。Eclipse默认的classpath路径是项目路径下的build/classes,注意不要被你的ant写的build覆盖了,而ant的build又没有编译test包。最终找不到测试类。


下面先写一个基本的测试类,其他的只要继承这个类并添加test方法即可。

--------------------------------------------------------------------------------

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;


public class BaseDaoTestCaseJunit3 extends
 AbstractTransactionalDataSourceSpringContextTests {
 
 protected final static Log log = LogFactory.getLog(BaseDaoTestCaseJunit3.class);
 
 @Override
 protected String[] getConfigLocations(){
 this.setAutowireMode(AUTOWIRE_BY_NAME);
 return new String[]{"classpath:/applicationContext.xml","classpath:/spring-config-*.xml"};
 }
 
 public void testConfig() {       
       assertNotNull("spring-mock context has bean init()",this.applicationContext);
    }
}

--------------------------------------------------------------------------------

下面这个类继承自上面的BaseDaoTestCaseJunit3,只是测试了下CustInfoDao里面的findByEmail方法。
import com.psi.domain.CustInfo;


public class CustInfoDaoTests3 extends BaseDaoTestCaseJunit3 {
 private CustInfoDao ciDao;
 private CustInfo ci;
 
 public CustInfoDaoTests3(){}
 
 public void setCustInfoDao(CustInfoDao ciDao){
 this.ciDao = ciDao;
 }


 public void getList(){
 try{
 ci = ciDao.findByEmail("sue76543@ms5.url.com.tw"); //此方法直接返回对象.
 assertNotNull(ci.getId());
 }catch(Exception e){
 e.printStackTrace();
 }
 }
}

--------------------------------------------------------------------------------

 

下面讲讲Junit4.4的写法:
Junit4用了完全不同于Junit3的写法,它的配置文件等都只需要在annotation里标注即可。TransactionManager是你在application里配置的TransactionManager。

--------------------------------------------------------------------------------

package com.psi.dao;


import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/applicationContext.xml","classpath:/spring-config-*.xml"})
@TransactionConfiguration(transactionManager="transactionManager",defaultRollback=true)
@Transactional
public class BaseDAOTestCaseJunit44 {
 //本类作为基类,所有要用到的东西都在annotation里配置了。所以什么内容都不用写了。
}

--------------------------------------------------------------------------------
//Dao测试类继承自上面的基类,并添加了个测试方法findByEmail。


import static org.junit.Assert.*;


import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;


import com.psi.domain.CustInfo;


public class CustInfoDaoTests extends BaseDAOTestCaseJunit44 {
 private CustInfoDao ciDao;
 private CustInfo ci;
 
 public CustInfoDaoTests(){}
 
 @Autowired
 public void setCustInfoDao(CustInfoDao ciDao){
 this.ciDao = ciDao;
 }
 
 @Before
 public void init(){}
 
 @Test
 public void getList(){
 try{
 ci = ciDao.findByEmail("sue76543@ms5.url.com.tw");
 assertNotNull(ci.getId());
 }catch(Exception e){
 e.printStackTrace();
 }
 }
}

--------------------------------------------------------------------------------
就这么简单,但是要注意要加载相应的包,Spring-test.jar, apache的commons-下的包最好都加上。(项目中你基本都能用上)
还要注意你的配置文件路径。
我还碰到过下面这个错误:
Caused by: java.lang.NullPointerException
    at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:374)
这是Eclipse的Bug,它在测试环境下不能自动加载到SystemLibrary下的所有包,所以你需要将你的Library改成user-library即可。