论坛首页 Java企业应用论坛

spring单元测试很简单?吐血

浏览 17823 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-12-09  
测试代码里面控制事务?测试代码脏数据?测试代码不是这样做的.......

测试代码要有独立性:test a的成功不应该依赖于test b的成功,test a的失败不能影响到test b的测试。

事务控制就更压根不是测试代码的事情

dbunit这种东西不实用,在你的setup里面每次都建立一个空的db不就行了么?
0 请登录后投票
   发表时间:2004-12-09  
Readonly 写道

setup里面每次都建立一个空的db不就行了么?


   可行,但是每个用例都要建立db,创建表单,删除一个db.......汗

我去实践下先
0 请登录后投票
   发表时间:2004-12-09  
Spring的注入动作很复杂啊!
有很多不为人知的地方。
0 请登录后投票
   发表时间:2004-12-09  
我在使用Spring的时候,测试的主要是自己的业务逻辑,对于接口部分相对来说测得比较少。正如gigix所说,测试业务逻辑只要new出一个对象,把各个属性set进去就可以了,这种单元测试与Spring一点关系都没有。

单元测试怎么做往往取决于你是如何设计的,如果你觉得自己的代码不方便测试,那你应该考虑是不是自己的设计有问题。比如单元测试非要连接数据库吗?比如测试一个bean要set那么多属性吗?

《JUnit In Action》谈到了许多测试方法,你可以看一下。
0 请登录后投票
   发表时间:2004-12-10  
做spring dao的单元测试的确会遇到事务、OpenSessionInView等问题,spring论坛很早就谈论了这些问题。建议直接去他的官方论坛查找,这样比较实际些。

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

基类:SpringTestCase
abstract public class SpringTestCase extends DatabaseTestCase

继承DatabaseTestCase需要复写几个方法

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

测试环境所需的数据源、数据文件,数据库属性我都用properties文件在外部设置,所以会出现props.getProperty(APP_DATASET)的语句,这不是必须的。你完全可以去掉这种语句。
  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格式的数据文件。
  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都继承自该基类。这样你就不用操心数据污染问题了。

至于测试中的事务问题,我就不多罗嗦了,贴出代码。大家一看就知道如何在测试中使用该类。
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。那么测试类只需要继承自下面的类即可。
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 请登录后投票
   发表时间:2004-12-11  
推荐使用DBUnit
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics