JUnit关于数据库访问的单元测试 (fi)

  • 数据库集成单元测试--------这类测试主要是检测数据库的功能:连接,查询,存储过程,触发,约束以及引用完整性.这些测试必须在容器内并且有数据 源相连的情况下进行.有很多第三方工具可以用来做这种测试,比如用cactus来进行容器内测试,DbUnit来预载测试数据库.      为了运行集成单元测试,我们的测试框架需要有两个功能:将测试数据预置进数据库的能力和从运行的容器内进行测试的能力.      我们的测试策略是用JBoss做为J2EE容器.MySQL作为测试数据库.Cactus作为测试代理.DbUnit作为装载及比较数据的工具,Ant作为运行测试工具.下面让我们进入测试吧.
       
              编写真正的JdbcDataAccessManager类:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.beanutils.RowSetDynaClass;

public class JdbcDataAccessManager implements DataAccessManager
{
    private DataSource dataSource;
    
    public JdbcDataAccessManager() throws NamingException
    {
        this.dataSource = getDataSource();
    }

    protected DataSource getDataSource() throws NamingException
    {
        InitialContext context = new InitialContext();
        DataSource dataSource = 
            (DataSource) context.lookup("java:/MySqlDS");
        return dataSource;
    }

    protected Connection getConnection() throws SQLException
    {
        return this.dataSource.getConnection();
    }

    public Collection execute(String sql) throws Exception
    {
        Connection connection = getConnection();

        // For simplicity, we'll assume the SQL is a SELECT query
        ResultSet resultSet = 
            connection.createStatement().executeQuery(sql);

        RowSetDynaClass rsdc = new RowSetDynaClass(resultSet);

        resultSet.close();
        connection.close();

        return rsdc.getRows();
    }
}

     注意要配置一个mysql数据源.假设在mysql数据库里建了一个叫jbossdb的数据库.然后在%JBOSS_HOME%/docs/examples/jca目录下找到mysql-ds.xml文件,对它进行编辑.

<?xml version="1.0" encoding="UTF-8"?>

<!-- ===================================================================== -->
<!--                                                                       -->
<!--  JBoss Server Configuration                                           -->
<!--                                                                       -->
<!-- ===================================================================== -->

<!-- $Id: mysql-ds.xml,v 1.1 2002/07/22 22:57:24 d_jencks Exp $ -->
<!-- ==================================================================== -->
<!--  Datasource config for MySQL using 2.0.11 driver                     -->
<!-- ==================================================================== -->


<datasources>
  <local-tx-datasource>
    <jndi-name>MySqlDS</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/jbossdb</connection-url>
    <driver-class>org.gjt.mm.mysql.Driver</driver-class>
    <user-name>sa</user-name>
    <password></password>
  </local-tx-datasource>

</datasources>


保存以后考到%JBOSS_HOME%/server/default/deploy目录下(假设你的JBOSS服务器以default模式起).下面编写测试代码:

import java.util.Collection;
import java.util.Iterator;

import javax.naming.InitialContext;

import org.apache.cactus.ServletTestCase;
import org.apache.commons.beanutils.DynaBean;
import org.dbunit.database.DatabaseDataSourceConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;

public class TestJdbcDataAccessManagerIC extends ServletTestCase
{
    protected void setUp() throws Exception
    {
        IDatabaseConnection connection = 
            new DatabaseDataSourceConnection(new InitialContext(),
            "java:/MySqlDS");

        IDataSet dataSet = new FlatXmlDataSet(
            this.getClass().getResource(
            "/junitbook/database/data.xml"));

        try
        {
            DatabaseOperation.CLEAN_INSERT.execute(connection, 
                dataSet);
        }
        finally
        {
            connection.close();
        }
    }

    public void testExecuteOk() throws Exception
    {
        JdbcDataAccessManager manager = 
            new JdbcDataAccessManager();

        Collection result = 
            manager.execute("SELECT * FROM CUSTOMER");

        Iterator beans = result.iterator();

        assertTrue(beans.hasNext());
        DynaBean bean1 = (DynaBean) beans.next();
        assertEquals("John", bean1.get("firstname"));
        assertEquals("Doe", bean1.get("lastname"));

        assertTrue(!beans.hasNext());
    }
}


在setup()里我们利用DbUnit从一个xml文件转载测试数据到数据库里.这里需要一个xml文件data.xml

   <dataset>
    <CUSTOMER FIRSTNAME="John" LASTNAME="Doe"/>
</dataset>
可以把它和测试代码文件放在同一个目录下.这个TestCase就是先在数据库里的Customer表里加一条记录,再进行测试.table我们可以利用ant来建,先编写一个data.sql

CREATE TABLE CUSTOMER (lastname varchar primary key, 
    firstname varchar);


. 注意所有文件以及需要的包的安放按照junit test的传统安置方式安放.好,要用ant来运行了,先写build.xml

build.properties

cactus.home.jboss3x = E:/JBoss/jboss-3.2.3/jboss-3.2.3

database = //localhost:3306/jbossdb

lib.dir = ../repository   

mysqldb.jar = ${cactus.home.jboss3x}/server/default/lib/mm.mysql-2.0.4-bin.jar

beanutils.jar = ${lib.dir}/commons-beanutils/jars/commons-beanutils-1.6.1.jar
collections.jar = ${lib.dir}/commons-collections/jars/commons-collections-2.1.jar
servlet.jar = ${lib.dir}/servletapi/jars/servletapi-2.3.jar

cactus.jar = ${lib.dir}/cactus/jars/cactus-1.6.1.jar
cactus.ant.jar = ${lib.dir}/cactus/jars/cactus-ant-1.6.1.jar
aspectjrt.jar = ${lib.dir}/aspectj/jars/aspectjrt-1.1.1.jar
dbunit.jar = ${lib.dir}/dbunit/jars/dbunit-1.5.5.jar
exml.jar = ${lib.dir}/dbunit/jars/exml-dbunit-1.5.5.jar
logging.jar = ${lib.dir}/commons-logging/jars/commons-logging-1.0.3.jar
httpclient.jar = ${lib.dir}/commons-httpclient/jars/commons-httpclient-2.0-rc1.jar

build.xml

<?xml version="1.0"?>

<project name="Database" default="test" basedir=".">

  <property file="build.properties.sample"/>
  <property name="conf.dir" location="conf"/>
    
  <target name="compile">
    <mkdir dir="target/classes"/>
    <javac destdir="target/classes" srcdir="src/java">
      <classpath>
        <pathelement location="${beanutils.jar}"/>
        <pathelement location="${servlet.jar}"/>
      </classpath>
    </javac>
  </target>
    
  <target name="war" depends="compile">
    <war destfile="target/database.war" 
        webxml="src/webapp/WEB-INF/web.xml">
      <classes dir="target/classes"/>
      <lib file="${beanutils.jar}"/>
      <lib file="${collections.jar}"/>
    </war>
  </target>

  <target name="createdb" depends="war">
    <sql driver="org.gjt.mm.mysql.Driver"
        url="jdbc:mysql{database}"
        userid="root"
        password="">          
      <fileset dir="${conf.dir}">
        <include name="data.sql" />
      </fileset>
      <classpath>
        <pathelement location="${mysqldb.jar}"/>
      </classpath>
    </sql>
  </target>

  <target name="clean">
    <delete dir="target"/>
  </target>

  <!-- Targets related to Cactus testing -->
    
  <target name="compile.cactustest" depends="createdb">
    <mkdir dir="target/cactus-test-classes"/>
    <javac destdir="target/cactus-test-classes" 
        srcdir="src/test-cactus">
      <classpath>
        <pathelement location="target/classes"/>
        <pathelement location="${beanutils.jar}"/>
        <pathelement location="${dbunit.jar}"/>
        <pathelement location="${cactus.jar}"/>
      </classpath>
    </javac>
    <copy todir="target/cactus-test-classes">
      <fileset dir="src/test-cactus">
        <include name="**/*.xml"/>
      </fileset>
    </copy>
  </target>
        
  <target name="test" depends="war,compile.cactustest">

    <taskdef resource="cactus.tasks">
      <classpath>
        <pathelement location="${cactus.ant.jar}"/>
        <pathelement location="${cactus.jar}"/>
        <pathelement location="${logging.jar}"/>
        <pathelement location="${aspectjrt.jar}"/>
        <pathelement location="${httpclient.jar}"/>
      </classpath>
    </taskdef>

    <cactifywar srcfile="target/database.war"
        destfile="target/test.war">
      <classes dir="target/cactus-test-classes"/>
      <lib file="${dbunit.jar}"/>
      <lib file="${exml.jar}"/>
    </cactifywar>

    <cactus warfile="target/test.war" fork="yes" printsummary="yes"
        haltοnerrοr="true" haltonfailure="true">
      <containerset>
        <jboss3x dir="${cactus.home.jboss3x}" 
            output="target/jbossresult.txt">
        </jboss3x>
      </containerset>
      <formatter type="brief" usefile="false"/>
      <batchtest>
        <fileset dir="src/test-cactus">
          <include name="**/TestJdbcDataAccessManagerIC.java"/>
        </fileset>
      </batchtest>
      <classpath>
        <pathelement location="target/classes"/>
        <pathelement location="target/cactus-test-classes"/>
        <pathelement location="${dbunit.jar}"/>
      </classpath>
    </cactus>

  </target>
    
</project>


接着我们就可以run case了,我试了一下没问题,若有问题,应该是配置或版本出了问题.

       我本人对JUnit进行数据库测试的看法是,在测试之前一定要有一个好的测试策略,在这基础之上在进行测试代码的编写.对数据库业务逻辑和数据库访问代码 的测试代码编写相对简单一些.对数据库进行集成测试要复杂和麻烦一些,但在这过程中能学到不少东西和加深对一些过程和配置的理解.

      以上是我一些不成熟的学习心得,在这抛砖引玉,希望更多的同行来讨论.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值