`
凯旋人生
  • 浏览: 61814 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

DBUnit

阅读更多

DBUnit官方网站:www.dbunit.org

About DbUnit

DbUnit is a JUnit extension (also usable with Ant) targeted at database-driven projects that, among other things, puts your database into a known state between test runs. This is an excellent way to avoid the myriad of problems that can occur when one test case corrupts the database and causes subsequent tests to fail or exacerbate the damage.

DbUnit has the ability to export and import your database data to and from XML datasets. Since version 2.0, DbUnit can also work with very large datasets when used in streaming mode. DbUnit can also help you to verify that your database data match an expected set of values.

1.添加dbunit-2.3.0.jar 

DBUnit依赖于Simple Logging Facade for Java (SLF4J)项目 官网:http://www.slf4j.org/

2.添加slf4j-api-1.5.3.jar

3.添加slf4j-jcl-1.5.3.jar

SLF4J依赖于Apache的 Commons-Logging.

4.添加commons-logging.jar

★ 导出数据库中的数据到xml文件

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

package com.test.dbunit;

import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatDtdDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;

public class Test {
 public static void main(String[] args) throws Exception {
  
  Class.forName("com.mysql.jdbc.Driver");
  Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost/dbunit","root","admin");
  //使用DBunit的DatabaseConnection类封装jdbc的连接,它实现了接口IDatabaseConnection
  IDatabaseConnection connection =new DatabaseConnection(conn);
  //QueryDataSet和.net中的数据集的概念类似,它是数据库的一个映像
  QueryDataSet partial=new QueryDataSet(connection);
  //把task表中的数据导出到xml文件中
  partial.addTable("task");
  
  //partial.addTable("users","select * from users where id= 1 ");
  partial.addTable("users");
  //把数据内容导出到xml文件中
  FlatXmlDataSet.write(partial,new FileOutputStream("partial.xml"));
  
  //将数据库中所有的数据导出
  IDataSet full =connection.createDataSet();
  FlatXmlDataSet.write(full, new FileOutputStream("full.xml"));
  //导出Dtd文件
  FlatDtdDataSet.write(full, new FileOutputStream("full.dtd"));
 }

}
------------------------------------------------------------------------------------------------------------

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE dataset SYSTEM "full.dtd">
<dataset>
  <task/>
  <users id="1" username="张三" password="123"/>
  <users id="2" username="李四" password="456"/>
  <users id="3" username="王五" password="789"/>
</dataset>
------------------------------------------------------------------------------------------------------------

<!ELEMENT dataset (
    task*,
    users*)>

<!ELEMENT task EMPTY>
<!ATTLIST task
    id CDATA #IMPLIED
    name CDATA #IMPLIED
    description CDATA #IMPLIED
>

<!ELEMENT users EMPTY>
<!ATTLIST users
    id CDATA #REQUIRED
    username CDATA #REQUIRED
    password CDATA #REQUIRED
>

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

//使用dbunti测试的简单例子

package com.test.dbunit;

import java.io.File;
import java.io.FileInputStream;

import org.dbunit.Assertion;
import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.SortedTable;
import org.dbunit.dataset.filter.DefaultColumnFilter;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;

public class SampleTest extends DBTestCase{
    //重写构造方法
 public SampleTest(String name){
  super(name);
  //在系统属性中添加数据库练接用到的属性
  System.setProperty(
    PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,
    "com.mysql.jdbc.Driver");
  System.setProperty(
    PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL,
    "jdbc:mysql://localhost/dbunit");
  System.setProperty(
    PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME,
    "root");
  System.setProperty(
    PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD,
    "admin");
 }
 /**
  * 在每次测试执行之前都先执行getSetUpOperation()操作
  */
 public DatabaseOperation getSetUpOperation() throws Exception{
  //默认在setUPOperation中就是执行CLEAN_INSERT ,
  //CLEAN_INSERT是DELETE_ALL和INSERT的组合,数据库会恢复到xml文件中的数据。
  return DatabaseOperation.CLEAN_INSERT;
  //刷新会更新xml内容到数据库中,数据存,xml中都存在的updata,数据库不存在insert,
  //数据库中有xml中没有的保持不变
  //return DatabaseOperation.REFRESH;
 }
 /**
  * 每次测试执行之后会执行该操作。
  */
 public DatabaseOperation getTearDownOperation() throws Exception{
  //什么都不做--默认
  //return DatabaseOperation.NONE;
  //清空数据库
  return DatabaseOperation.DELETE_ALL;
 }
 
 /**
  * 将数据文件转换成数据集,这个方法是在dbunit启动的时候自动启动
  */
 @Override
 protected IDataSet getDataSet() throws Exception {
  return new FlatXmlDataSet(new FileInputStream("full.xml"));
 }
 
 public void test1() throws Exception{
  IDataSet dataSet = getConnection().createDataSet();
  //数据库中实际的表
  ITable actualTable = dataSet.getTable("users");
  //期望值
  IDataSet dataSet2 = new FlatXmlDataSet(new File("full.xml"));
  ITable expectedTable = dataSet2.getTable("users");
  //DBUnit的Assertion类
  Assertion.assertEquals(expectedTable,actualTable);
 }
 
 //比较过滤二种方法之一,包含哪些列
 public void test2() throws Exception{
     IDataSet dataSet = getConnection().createDataSet();
     ITable  actualTable = dataSet.getTable("users");
  
     //期望值-没有id列
     IDataSet dataSet2 = new FlatXmlDataSet(new File("Full2.xml"));
     ITable expectedTable = dataSet2.getTable("users");
     //用过滤器过滤掉actualtable的中的id列
     actualTable = DefaultColumnFilter.includedColumnsTable(actualTable,
       expectedTable.getTableMetaData().getColumns());
     Assertion.assertEquals(expectedTable, actualTable);
 }
 //方法2,比较用户名相同的。排除掉不需要比较的各个字段,
 public void test3() throws Exception{
  IDataSet dataSet =getConnection().createDataSet();
  ITable actualTable = dataSet.getTable("users");
  
  IDataSet dataSet2 = new FlatXmlDataSet(new File("full2.xml"));
  ITable expectedTable = dataSet2.getTable("users");
  
  ITable filterActualTable =DefaultColumnFilter.excludedColumnsTable(
    actualTable, new String[]{"id","password"});
  
        ITable filterExpectedTable =DefaultColumnFilter.excludedColumnsTable(
          expectedTable,new String[]{"password"});
       
        Assertion.assertEquals(filterExpectedTable,filterActualTable);
 }
 //排序表格
 public void test4() throws Exception{
  IDataSet dataSet = getConnection().createDataSet();
  //数据库中实际的表
  ITable actualTable = dataSet.getTable("users");
  //期望值
  IDataSet dataSet2 = new FlatXmlDataSet(new File("expected.xml"));
  ITable expectedTable = dataSet2.getTable("users");
  //把表按照字段排序,默认是按照字符串排序
  SortedTable sortedTable1 = new SortedTable(actualTable,new String[]{"id"});
  //按照数据库中字段排序
  sortedTable1.setUseComparable(true);
  SortedTable sortedTable2 = new SortedTable(expectedTable,new String[]{"id"});
  //按照数据库中字段排序
  sortedTable2.setUseComparable(true);
  //DBUnit的Assertion类
  Assertion.assertEquals(sortedTable2,sortedTable1);
 }
// 表操作测试的实例:

public void testSave() throws Exception{
  UsersDB db =new UsersDB();
  Users users =new Users();
  users.setId(9);
  users.setUserName("langsin");
  users.setPassword("helloworld");
  
  db.save(users);
  IDataSet dataSet = getConnection().createDataSet();
  ITable actualTable = dataSet.getTable("users");
  IDataSet dataSet2 = new FlatXmlDataSet(new File("expected2.xml"));
  ITable expectedTable =dataSet.getTable("users");
  Assertion.assertEquals(expectedTable, actualTable);
}

 

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

package com.test.bean;

public class Users {
 private int id;
 private String userName;
 private String password;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 

}

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

package com.test.dbunit;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.test.bean.Users;

public class UsersDB {
 public void save(Users users){
  Connection conn=null;
  try{
   Class.forName("com.mysql.jdbc.Driver");
   conn=DriverManager.getConnection("jdbc:mysql://localhost/dbunit",
     "root", "admin");
   String sql="insert into users(id,username,password) values(?,?,?)";
   PreparedStatement ps =conn.prepareStatement(sql);
   ps.setInt(1, users.getId());
   ps.setString(2,users.getUserName());
   ps.setString(3,users.getPassword());
   ps.executeUpdate();
  }catch(Exception ex){
   ex.printStackTrace();
  }finally
  {
   if(null!= conn)
   {
    try
    {
     conn.close();
    }catch(SQLException e){
     e.printStackTrace();
    }
    
   }
  }
 }

}
---------------------------expected2.xml------------------------------

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE dataset SYSTEM "full.dtd">
<dataset>
  <task/>
  <users id="1" username="张三" password="123"/>
  <users id="2" username="李四" password="456"/>
  <users id="3" username="王五" password="789"/>
  <users id="9" username="langsin" password="helloworld"/>
</dataset>

***********************************************************************

 使用DBUnit进行单元测试的基本流程

1.根据业务,做好测试用的准备数据和预想结果数据,通常为XML格式文件。

2.在setUp()方法里面边备份数据库中的关联表。

3.在setUP()方法里面边读入准备数据。

4.对测试类的对应测试方法进行调用:执行对象方法,把数据库中的实际执行

结果和预想结果进行比较。

5.在tearDown()方法里面,把数据库还原到测试前状态。

***********************************************************************

 

Getting Started

  1. Database setup with DBTestCase subclass
  2. Database setup with your own TestCase subclass
  3. Database data verification
  4. DbUnit Ant task and Canoo WebTest

Database setup with DBTestCase subclass

Step 1: Create your dataset file

Your test need some data to work with. This means you must create a dataset. In most situations you will work with xml datasets. You can manually create a flat XML dataset from scratch or create one by exporting some data from your database.

Step 2: Extend the DBTestCase class

Now you need to create a test class. The easiest way to use Dbunit is to make your test class extend the DBTestCase class. DBTestCase extends the JUnit TestCase class. A template method is required to be implemented: getDataSet() to return the dataset you created in step 1. DBTestCase relies on a IDatabaseTester to do its work, the default configuration uses PropertiesBasedJdbcDatabaseTester, it locates configuration for the DriverManager within the Sytem properties. The simplest way to configure it would be in the constructor of your test class. You may modify this behavior by overriding getDatabaseTester(),CLEAN_INSERT operation before executing each test and performs no cleanup operation afterward. You can modify this behavior by overriding getSetUpOperation() and getTearDownOperation().

Database setup with your own TestCase subclass

In order to use Dbunit you are not required to extend the DBTestCase class. You can override the standard JUnit setUp() method and execute the desired operation on your database. Do something similar in teardown() if you need to perform clean-up.

For example:

public class SampleTest extends TestCase { public SampleTest(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); // initialize your database connection here IDatabaseConnection connection = null; // ... // initialize your dataset here IDataSet dataSet = null; // ... try1 { DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet); } finally { connection.close(); } } ... }

 

Since version 2.2 you may use the new IDatabaseTester to accomplish the same feat. As explained in the previous topic, DBTestCase uses a IDatabaseTester internally to do its work; your test class may also use this feature to manipulate DataSets. Currently there are 4 convenient implementations:

JdbcDatabaseTester uses a DriverManager to create connections.
PropertiesBasedJdbcDatabaseTester also uses DriverManager, but the configuration is taken from system properties.
This is the default implementation used by DBTestCase.
DataSourceDatabaseTester uses a javax.sql.DataSource to create connections.
JndiDatabaseTester uses a javax.sql.DataSource located through JNDI.

You may also provide your own IDatabaseTester implementation. It is recommended to use AbstractDatabaseTester as a starting point.

Example:

public class SampleTest extends TestCase { private IDatabaseTester databaseTester; public SampleTest(String name) { super(name); } protected void setUp() throws Exception { databaseTester = new JdbcDatabaseTester("org.hsqldb.jdbcDriver", "jdbc:hsqldb:sample", "sa", ""); // initialize your dataset here IDataSet dataSet = null; // ... databaseTester.setDataSet( dataSet ); // will call default setUpOperation databaseTester.onSetUp(); } protected void tearDown() throws Exception { // will call default tearDownOperation databaseTester.onTearDown(); } ... }

 

Database data verification

Dbunit provides support for verifying whether two tables or datasets contain identical data. The following two methods can be used to verify if your database contains the expected data during test cases execution.

public class Assertion { public static void assertEquals(ITable expected, ITable actual) public static void assertEquals(IDataSet expected, IDataSet actual) }

 

Sample

The following sample, show how to compare a database table snapshot against a flat XML table.

public class SampleTest extends DBTestCase { public SampleTest(String name) { super(name); } // Implements required setup methods here ... public void testMe() throws Exception { // Execute the tested code that modify the database here ... // Fetch database data after executing your code IDataSet databaseDataSet = getConnection().createDataSet(); ITable actualTable = databaseDataSet.getTable("TABLE_NAME"); // Load expected data from an XML dataset IDataSet expectedDataSet = new FlatXmlDataSet(new File("expectedDataSet.xml")); ITable expectedTable = expectedDataSet.getTable("TABLE_NAME"); // Assert actual database table match expected table Assertion.assertEquals(expectedTable, actualTable); } }

 

The actual dataset is a database snapshot you want to verify against an expected dataset. As its name imply, the expected dataset contains the expectation values.

The expected dataset must be different from the one you have used to setup your database. Therefore you need two datasets to do that; one to setup your database before a test and another to provide the expected data during the test.

Using a query to take the database snapshot

You can also verify if the result of a query match an expected set of data. The query can be used to select only a subset of a table or even join multiple tables together.

ITable actualJoinData = getConnection().createQueryTable("RESULT_NAME", "SELECT * FROM TABLE1, TABLE2 WHERE ...");

 

Ignoring some columns in comparison

Sometimes this is desirable to ignore some columns to perform the comparison; particularly for primary keys, date or time columns having values generated by the code under test. One way to do this is to omit to declare unwanted columns in your expected table. You can then filter the actual database table to only expose the expected table columns.
The following code snippet shows you how to filter the actual table. To works, the actual table MUST contain at least ALL the columns from the expected table. Extra columns can exist in the actual table but not in the expected one.

ITable filteredTable = DefaultColumnFilter.includedColumnsTable(actual, expected.getTableMetaData().getColumns()); Assertion.assertEquals(expected, filteredTable);

 

A major limitation of this technique is that you cannot use a DTD with your expected flat XML dataset. With a DTD you need to filter columns from both the expected and the actual table. See the FAQ about excluding some table columns at runtime.

Row ordering

By default, database table snapshot taken by DbUnit are sorted by primary keys. If a table does not have a primary key or the primary key is automatically generated by your database, the rows ordering is not predictable and assertEquals will fail.

You must order your database snapshot manually by using IDatabaseConnection.createQueryTable with an "ORDER BY" clause. Or you can use the SortedTable decorator class like this:

Assertion.assertEquals(new SortedTable(expected), new SortedTable(actual, expected.getTableMetaData()));
Note that the SortedTable uses the string value of each column for doing the sort by default. So if you are sorting a numeric column you notice that the sort order is like 1, 10, 11, 12, 2, 3, 4. If you want to use the columns datatype for sorting (to get the columns like 1, 2, 3, 4, 10, 11, 12) you can do this as follows:
SortedTable sortedTable1 = new SortedTable(table1, new String[]{"COLUMN1"}); sortedTable1.setUseComparable(true); // must be invoked immediately after the constructor SortedTable sortedTable2 = new SortedTable(table2, new String[]{"COLUMN1"}); sortedTable2.setUseComparable(true); // must be invoked immediately after the constructor Assertion.assertEquals(sortedTable1, sortedTable2);
The reason why the parameter is currently not in the constructor is that the number of constructors needed for SortedTable would increase from 4 to 8 which is a lot. Discussion should go on about this feature on how to implement it the best way in the future.

 

DbUnit Ant task and Canoo WebTest

By Eric Pugh

With Dbunit Ant tasks, Dbunit makes it much easier to run Canoo WebTest scripts for database centric applications. WebTest is a tool to simulate a user's browser clicking through the pages on a web site. It allows you to create a series of Ant based tests for your website. In fact, this can be used to perform User Acceptance tests for websites built using non Java technologies like ColdFusion or ASP! This document walks you through a suggested format for storing tests.

Step 1: Create your dataset file

Your first step is to create your dataset file that you want to load into your database before running your WebTest script. Use one of the various methods described above. Put the various datasets you need in a /data directory.

Step 2: Create your Ant build.xml file

A suggested setup is to have a single build.xml file that is the entry point for all your tests. This would include a couple targets like:

  1. test: Runs all the testSuites that you have created
  2. test:single: Runs a single test in a specific testSuite
  3. test:suite: Runs all the tests for a specific testSuite

 

Step 3: Create your various Test Suites

Once you have your build.xml file set up, you can now call the various TestSuites. Create a separate TestSuiteXXX.xml for the various modules that you would like to test. In your TestSuiteXXX.xml, you should have your default target testSuite call all the testcases you have definied:

<target name="testSuite"> <antcall target="unsubscribeEmailAddressWithEmail"/> <antcall target="unsubscribeEmailAddressWithEmailID"/> <antcall target="unsubscribeEmailAddressWithNewEmailAddress"/> <antcall target="subscribeEmailAddressWithOptedOutEmail"/> <antcall target="subscribeEmailAddressWithNewEmailAddress"/> <antcall target="subscribeEmailAddressWithInvalidEmailAddress"/> </target>

 

This way you can either run all the test's in your Test Suite, or just run a specific one, all from build.xml!

Step 4: Create your various Tests

Now you need to write your various testcases. For more information on WebTest, please refer to the WebTest home page. If you have find you are duplicating pieces of XML, then place them in a /includes directory. If you have a single set of properties, then load them as part of build.xml by specifing them in your build.properties file. If you have multiple databases you need to connect to, then declare your sql connection properties in a TestSuiteXXX.properties file that you load on a per suite basis. In this example, we are using doing a clean insert into the database, and using the MSSQL_CLEAN_INSERT instead of CLEAN_INSERT because of the requirement to do identity column inserts.

<target name="subscribeEmailAddressWithOptedOutEmail"> <dbunit driver="${sql.jdbcdriver}" url="${sql.url}" userid="${sql.username}" password="${sql.password}"> <operation type="MSSQL_CLEAN_INSERT" src="data/subscribeEmailAddressWithOptedOutEmail.xml" format="flat"/> </dbunit> <testSpec name="subscribeEmailAddressWithOptedOutEmail"> &amp;sharedConfiguration; <steps> <invoke stepid="main page" url="/edm/subscribe.asp?e=subscribeEmailAddressWithOptedOutEmail@test.com" save="subscribeEmailAddressWithNewEmailAddress"/> <verifytext stepid="Make sure we received the success message" text="You have been subscribed to the mailing list"/> </steps> </testSpec> </target>

 

Sample Directory Layout

When you are done, you will have a series of files that look like this:

 

using one of the other 3 provided IDatabaseTester implementations or your own. You may also use the other subclasses of DBTestCase described in the next table:

JdbcBasedDBTestCase uses a DriverManager to create connections (with the aid of a JdbcDatabaseTester).
DataSourceBasedDBTestCase uses a javax.sql.DataSource to create connections (with the aid of a DataSourceDatabaseTester).
JndiBasedDBTestCase uses a javax.sql.DataSource located through JNDI (with the aid of a JndiDatabaseTester).

Following is a sample implementation that returns a connection to a Hypersonic database and a xml dataset:

public class SampleTest extends DBTestCase { public SampleTest(String name) { super( name ); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.hsqldb.jdbcDriver" ); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:hsqldb:sample" ); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa" ); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "" ); // System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_SCHEMA, "" ); } protected IDataSet getDataSet() throws Exception { return new FlatXmlDataSet(new FileInputStream("dataset.xml")); } }

 

Step 3: (Optional) Implement getSetUpOperation() and getTearDownOperation() methods

By default, Dbunit performs a

The following example demonstrates how you can easily override the operation executed before or after your test.

public class SampleTest extends DBTestCase { ... protected DatabaseOperation getSetUpOperation() throws Exception { return DatabaseOperation.REFRESH; } protected DatabaseOperation getTearDownOperation() throws Exception { return DatabaseOperation.NONE; } ... }

 

Step 4: Implement your testXXX() methods

Implement your test methods as you normally would with JUnit. Your database is now initialized before and cleaned-up after each test methods according to what you did in previous steps.


Core Components

This document attemps to give you an overview of the core classes that make up DbUnit. Following are the core interfaces or abstract classes:

ClassDescription
IDatabaseConnection Interface representing a DbUnit connection to a database.
IDataSet Interface representing a collection of tables.
DatabaseOperation Abstract class representing an operation performed on the database before and after each test.

IDatabaseConnection

The IDatabaseConnection interface represents a DbUnit connection to a database.

ClassDescription
DatabaseConnection Wraps a JDBC connection.
DatabaseDataSourceConnection Wraps a JDBC DataSource.

IDataSet

The IDataSet interface represents is a collection of tables. This is the primary abstraction used by DbUnit to manipulate tabular data.

Most commonly used implemetations:

ImplementationDescription
FlatXmlDataSet Reads and writes flat XML dataset document. Each XML element corresponds to a table row. Each XML element name corresponds to a table name. The XML attributes correspond to table columns.
Flat XML dataset document sample:
<!DOCTYPE dataset SYSTEM "my-dataset.dtd"> <dataset> <TEST_TABLE COL0="row 0 col 0" COL1="row 0 col 1" COL2="row 0 col 2"/> <TEST_TABLE COL1="row 1 col 1"/> <SECOND_TABLE COL0="row 0 col 0" COL1="row 0 col 1" /> <EMPTY_TABLE/> </dataset>

To specify null values, omit corresponding attribute. In the above example, missing COL0 and COL2 attributes of TEST_TABLE second row represents null values.
Table metadata is deduced from the first row of each table by default, whereas it is possible to enable the column sensing feature as described in differentcolumnnumberBeware you may get a NoSuchColumnException if the first row of a table has one or more null values. Because of that, this is highly recommended to use DTD. DbUnit will use the columns declared in the DTD as table metadata. DbUnit only support external system URI. The URI can be absolute or relative.
Another way to cope with this problem is to use the ReplacementDataSet.
XmlDataSet Reads and writes original XML dataset document. This format is very verbose and must conform to the following DTD:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT dataset (table+)> <!ELEMENT table (column*, row*)> <!ATTLIST table name CDATA #REQUIRED > <!ELEMENT column (#PCDATA)> <!ELEMENT row (value | null | none)*> <!ELEMENT value (#PCDATA)> <!ELEMENT null EMPTY>

XML dataset document sample:
<!DOCTYPE dataset SYSTEM "dataset.dtd"> <dataset> <table name="TEST_TABLE"> <column>COL0</column> <column>COL1</column> <column>COL2</column> <row> <value>row 0 col 0</value> <value>row 0 col 1</value> <value>row 0 col 2</value> </row> <row> <null/> <value>row 1 col 1</value> <null/> </row> </table> <table name="SECOND_TABLE"> <column>COLUMN0</column> <column>COLUMN1</column> <row> <value>row 0 col 0</value> <value>row 0 col 1</value> </row> </table> <table name='EMPTY_TABLE'> <column>COLUMN0</column> <column>COLUMN1</column> </table> </dataset>

StreamingDataSet Consumes a producer and expose its content as a dataset. Provides cursor like forward only access to it and only keeps the active row in memory. Can be used with FlatXmlProducer and XmlProvider.
This is a very efficient way to load XML dataset document when working with forward only database operations (UPDATE, INSERT, REFRESH).
Following sample shows how to load a flat XML dataset with the StreamingDataSet:
IDataSetProducer producer = new FlatXmlProducer( new InputSource("dataset.xml")); IDataSet dataSet = new StreamingDataSet(producer);
DatabaseDataSet Adapter that provides access to a database instance as a dataset. This class is not usually instantiated directly but from the factory method IDatabaseConnection.createDataSet().
QueryDataSet Holds collection of tables resulting from database queries.
Following sample snippet creates a dataset containing two tables: FOO, resulting from specified query and BAR, resulting from generated query "SELECT * FROM BAR".
QueryDataSet dataSet = new QueryDataSet(connection); dataSet.addTable("FOO", "SELECT * FROM TABLE WHERE COL='VALUE'"); dataSet.addTable("BAR");
DefaultDataSet Uses to create datasets programmatically.
CompositeDataSet Combines multiple datasets into a single logical dataset.
FilteredDataSet Decorator that exposes only some tables from decorated dataset. Can be used with different filtering strategies. Some strategies can include/exclude tables without altering their order while others expose tables with a different order. StrategyDescription
IncludeTableFilter Exposes only matching tables pattern without modifying the original table order. Support wildcards.
ExcludeTableFilter Hides matching tables pattern without modifying the original table order. Support wildcards.
SequenceTableFilter Exposes a configured table sequence and can be used to reorder dataset table. This is the original filtering strategy from DbUnit 1.x.
DatabaseSequenceFilter Automatically determine the tables order using foreign/exported keys information. This strategy is vendor independent and should work with any JDBC driver that implement the DatabaseMetaData.getExportedKeys() method.
Support simple multi-level dependency like this:
A / \ B C / \ D E
XlsDataSet Read and writes MS Excel dataset documents. Each sheet represents a table. The first row of a sheet defines the columns names and remaining rows contains the data.
ReplacementDataSet Decorator that replaces placeholder objects from the decorated dataset with replacement objects. Substring substitution is also possible.
Interestingly this provides a new way to specify null values in flat XML datasets. For example you can use a placeholder value, like "[NULL]" in your flat XML dataset and replace it with null at runtime.
<?xml version="1.0"?> <dataset> <TEST_TABLE COL0="row 0 col 0" COL1="[null]"/> <TEST_TABLE COL1="row 1 col 0" COL2="row 1 col 1"/> </dataset>

Loading the flat XML dataset:
ReplacementDataSet dataSet = new ReplacementDataSet( new FlatXmlDataSet(…)); dataSet.addReplacementObject("[NULL]", null);

You can choose to use a fail-fast replacement to ensure that all placeholders are actually set and no one is missing in the replacement map. If one is missing the replacement will fail immediately throwing an exception. (Note that the default behaviour is to leave the non-replaced placeholder there and proceeding work silently):
replacementDataSet.setStrictReplacement(true);

DatabaseOperation

DatabaseOperation is an abstract class that represents an operation performed on the database before and after each test.

The two most usefull operations are REFRESH and CLEAN_INSERT. They are the ones you will deal usualy with. They represent two testing strategies with different benefits and tradeoffs.

OperationDescription
DatabaseOperation.UPDATE This operation updates the database from the dataset contents. This operation assumes that table data already exists in the target database and fails if this is not the case.
DatabaseOperation.INSERT This operation inserts the dataset contents into the database. This operation assumes that table data does not exist in the target database and fails if this is not the case. To prevent problems with foreign keys, tables must be sequenced appropriately in the dataset.
DatabaseOperation.DELETE This operation deletes only the dataset contents from the database. This operation does not delete the entire table contents but only data that are present in the dataset.
DatabaseOperation.DELETE_ALL Deletes all rows of tables present in the specified dataset. If the dataset does not contains a particular table, but that table exists in the database, the database table is not affected. Table are truncated in reverse sequence.
DatabaseOperation.TRUNCATE Truncate tables present in the specified dataset. If the dataset does not contains a particular table, but that table exists in the database, the database table is not affected. Table are truncated in reverse sequence.
DatabaseOperation.REFRESH This operation literally refreshes dataset contents into the target database. This means that data of existing rows are updated and non-existing row get inserted. Any rows which exist in the database but not in dataset stay unaffected. This approach is more appropriate for tests that assume other data may exist in the database.
if they are correctly written, tests using this strategy can even be performed on a populated database like a copy of a production database.
DatabaseOperation.CLEAN_INSERT This composite operation performs a DELETE_ALL operation followed by an INSERT operation. This is the safest approach to ensure that the database is in a known state. This is appropriate for tests that require the database to only contain a specific set of data.
DatabaseOperation.NONE Empty operation that does absolutely nothing.
CompositeOperation This operation combines multiple operations into a single one.
TransactionOperation This operation decorates an operation and executes it within the context of a transaction.
IdentityInsertOperation This operation decorates an insert operation and disables the MS SQL Server automatic identifier generation (IDENTITY) during its execution. Use following constants InsertIdentityOperation.INSERT, InsertIdentityOperation.CLEAN_INSERT or InsertIdentityOperation.REFRESH instead of those defined in DatabaseOperation.

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics