Spring的单元测试

1:

我在web-inf下有个bean的配置片段
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/persist/jdbc.properties</value>
</list>
</property>
</bean>
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>/WEB-INF/persist/sqlMapConfig.xml</value>
</property>
</bean>

如果单元测试
使用
FileSystemXmlApplicationContext(locs)获得ApplicationContext,但是上面配置片段中的路径会找不到.


2:

alin_ass 写道:
我去试下,您有现成的测试代码吗?
我的结构是这样的
webapp
|
|--web-inf
.....|---bean1.xml
.....|---bean2.xml
.....|---bean3.xml
.....|---classes
................|---MyTestCase1.class


把你的bean.xml移到classpath下面(classes目录),比如com.javaeye这个package下面。

那么web.xml里面可以这样写:
xml代码: 


    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/com/javaeye/bean1.xml,
            classpath:/com/javaeye/bean2.xml
        </param-value>
    </context-param>



单元测试用ClassPathXmlApplicationContext

java代码: 


ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] {"com/javaeye/bean1.xml", "com/javaeye/bean2.xml"});



那些jdbc property和ibatis mapping文件的location也可以写成
classpath: xxx.properties

这样的好处是可以打一个jar包就把所有的东东就包含进去了......


3:

又学了一招
但是按照我的目录,配置文件放外部比较舒服点,测试只好写麻烦点拉

但是我不晓得怎么在测试里控制 数据库事务.比如下面的UserAccountDaoImpTest.testGetInsertUpdateDeleteAccount()
用SqlMapClient.startTranscation() commitTranscation()...会有问题

通过的测试
java代码: 


public class DaoImpTest extends TestCase {
        protected final void initDaoImp(SqlMapClientDaoSupport daoImp) throws Exception {
                String classesDirLoc = ClassLoader.getSystemResource("").getFile();
                File webinfDir = new File(classesDirLoc).getParentFile();

                //init data source
                InputStream is = new FileInputStream(new File(webinfDir,
                                "jdbc.properties"));
                Properties jdbcProperties = new Properties();
                jdbcProperties.load(is);
                BasicDataSource basicDS = new BasicDataSource();
                basicDS.setDriverClassName(jdbcProperties
                                .getProperty("jdbc.driverClassName"));
                basicDS.setUrl(jdbcProperties.getProperty("jdbc.url"));
                basicDS.setUsername(jdbcProperties.getProperty("jdbc.username"));
                basicDS.setPassword(jdbcProperties.getProperty("jdbc.password"));
                DataSource ds = basicDS;

                //init sqlMapClient
                Reader reader = new FileReader(new File(webinfDir, "sqlMapConfig.xml"));
                SqlMapClient sqlMapClient = new XmlSqlMapClientBuilder()
                                .buildSqlMap(reader);

                //init daoImp
                daoImp.setDataSource(ds);
                daoImp.setSqlMapClient(sqlMapClient);

        }
}



java代码: 


public class UserAccountDaoImpTest extends DaoImpTest {

        private UserAccountDao dao;

        protected void setUp() throws Exception {

                UserAccountDaoImp daoImp = new UserAccountDaoImp();
                this.initDaoImp(daoImp);
                this.dao = daoImp;

        }
        public void testGetInsertUpdateDeleteAccount() {...}
}


java代码: 


public class UserAccountDaoImp extends SqlMapClientDaoSupport implements
                UserAccountDao {...}




4:

spring dao的单元测试的确会遇到事务、OpenSessionInView等问题,spring论坛很早就谈论了这些问题。建议直接去他的官方论坛查找,这样比较实际些。

下面给出一些利用dbunit的一些代码片断

基类:SpringTestCase
java代码: 

abstract public class SpringTestCase extends DatabaseTestCase


继承DatabaseTestCase需要复写几个方法

getConnection方法是dbunit得到数据库连接的方法,这其中我除了设置设置了数据库属性为Oracle,因为默认dbunit不会去设置,具体文档dbunit写的很详细

测试环境所需的数据源、数据文件,数据库属性我都用properties文件在外部设置,所以会出现props.getProperty(APP_DATASET)的语句,这不是必须的。你完全可以去掉这种语句。
java代码: 

  protected IDatabaseConnection getConnection() throws Exception
  {
    DataSource ds = (DataSource) getBean(props.getProperty(BEAN_DATASOURCE));
    IDatabaseConnection conn = new DatabaseConnection(ds.getConnection(),
        props.getProperty(TEST_SCHEMA));
    conn.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
        new OracleDataTypeFactory());

    return conn;
  }



getDataSet方法设置你的测试数据源,也就是数据文件。这里我设置的是xml格式的数据文件。
java代码: 

  protected IDataSet getDataSet() throws Exception
  {
    try
    {
      InputStream in = new FileInputStream(props.getProperty(APP_DATASET));
      return new XmlDataSet(in);
    }
    catch (FileNotFoundException ex)
    {
      log.error(ex);
      throw new SpringTestCaseException(ex);
    }

  }



以后凡是要测试所有的Dao都继承自该基类。这样你就不用操心数据污染问题了。

至于测试中的事务问题,我就不多罗嗦了,贴出代码。大家一看就知道如何在测试中使用该类。
java代码: 

package com.idealbiz.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate.HibernateTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import net.sf.hibernate.SessionFactory;

/**
* $Id: HibernateTransactionUtils.java,v 1.9 2004/09/03 17:23:14 denis Exp $
* Class HibernateTransactionUtils
*
* <p>  Shanghai Ideal Information Industry (Group) Co.,Ltd.</p>
* @author denis  <tt>deniswang@sina.com</tt>
* 2004-9-2 17:50:02
*/

public class HibernateTransactionUtils
{
  private static final Log log = LogFactory
      .getLog(HibernateTransactionUtils.class);
  private PlatformTransactionManager ptm;
  private TransactionStatus status;
  private static HibernateTransactionUtils transactionUtils;
 
  protected HibernateTransactionUtils(SessionFactory sessionFactory)
  {
    log.info("Initialize HibnernateTransactionManager ...");
    ptm = new HibernateTransactionManager(sessionFactory);
  }

  public static HibernateTransactionUtils getNewInstance(SessionFactory sessionFactory)
  {
    if (transactionUtils == null)
    {
      transactionUtils = new HibernateTransactionUtils(sessionFactory);
    }
    return transactionUtils;
  }
 
  public void beginTransaction()
  {
    log.info("begin Transaction ...");
    status = ptm.getTransaction(new DefaultTransactionDefinition());
  }
 
  public void rollbackTransaction()
  {
    if (status != null)
    {
      log.info("rollback Transaction ...");
      ptm.rollback(status);
    }
    else
    {
      throw new IllegalStateException("Transaction status incorrect.");
    }
  }
 
  public void commitTransaction()
  {
    if (status != null)
    {
      log.info("commit Transaction ...");
      ptm.commit(status);
    }
    else
    {
      throw new IllegalStateException("Transaction status incorrect.");
    }
  }
}




如果你使用了OpenSessionInView的话,可能需要模仿这种环境以避免测试环境下的懒加载异常。例如测试Web Action。那么测试类只需要继承自下面的类即可。
java代码: 


package com.idealbiz.test;

import org.springframework.orm.hibernate.SessionFactoryUtils;
import org.springframework.orm.hibernate.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;

/**
* $Id: OpenSessionInTestCase.java,v 1.2 2004/09/08 07:59:06 denis Exp $
* Class OpenSessionInTestCase
*
* <p>  Shanghai Ideal Information Industry (Group) Co.,Ltd.</p>
* @author denis  <tt>deniswang@sina.com</tt>
* 2004-9-7 16:47:53
*/

public class OpenSessionInTestCase extends SpringTestCase
{
  protected final static String SESSION_FACTORY_NAME = "sessionFactory";
  private SessionFactory sessionFactory = null;
 
  public OpenSessionInTestCase(){ super(); }
  public OpenSessionInTestCase(String name) { super(name); }

 
  protected void setUp() throws Exception
  {
    super.setUp();
    sessionFactory = getSessionFactory();
    Session session = SessionFactoryUtils.getSession(sessionFactory, true);
    TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
  }
 
  protected void tearDown() throws Exception
  {
    SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
    SessionFactoryUtils.closeSessionIfNecessary(sessionHolder.getSession(), sessionFactory);
    super.tearDown();
  }
 
  public SessionFactory getSessionFactory()
  {
    if (sessionFactory == null)
    {
      sessionFactory = (SessionFactory) getBean(SESSION_FACTORY_NAME);
    }
    return sessionFactory;
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值