[Webtest] DBUnit integrated to Canoo?
Ben Cox
webtest@lists.canoo.com
Sun, 07 Apr 2002 00:26:13 -0800
This is a multi-part message in MIME format.
--------------070303070901040003070607
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
David,
Well, my partner and I made a DBUnit task for Ant (a bit less than
thoroughly commented, but it's not really that complicated!), which
sounds like what you'd like. We modelled it after the interface to the
<sql> task in ant. I've included the three Java files (including the
test case), and the XML files required to run the test. Please note a
couple of things:
- the pktabledef.sql contains a MySQL dump of the simple test tables
- the classes need to go into package com.insourcery.ant.dbunit
- the setUp method in DBUnitTaskTester refers to the buildfile.xml
without any path information, so keep that in mind.
Feel free to get in touch if you see any improvements that would
help, or if you just want to talk about the approach!
Enjoy,
Ben Cox && Tim Ruppert
David Eric Pugh wrote:
> Has anyone integrated DBUnit into Canoo/httpUnit?
>
> I am testing a very database intensive app, and I want to after each
> <testSpec> to reset my database to a known state. That way I can
validate
> that all my forign keys and other database related setting work, and that
> they don't change under me!
>
> I think I need to create my own version of testSpec like testSpecDB
that has
> as part of the setup and teardown resetting the database.
>
> Eric
>
>
> _______________________________________________
> WebTest mailing list
> WebTest@lists.canoo.com
> http://lists.canoo.com/mailman/listinfo/webtest
>
>
--------------070303070901040003070607
Content-Type: text/plain;
name="DBUnitTask.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="DBUnitTask.java"
package com.insourcery.ant.dbunit;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.Properties;
import java.sql.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import org.dbunit.DatabaseUnitException;
import org.dbunit.operation.OperationData;
/**
*
*/
public class DBUnitTask extends Task {
/**
* Database connection
*/
private Connection conn = null;
/**
* DB driver.
*/
private String driver = null;
/**
* DB url.
*/
private String url = null;
/**
* User name.
*/
private String userId = null;
/**
* Password
*/
private String password = null;
/**
* Operations
*/
private List operations = new ArrayList();
/**
* Set the JDBC driver to be used.
*/
public void setDriver(String driver) {
this.driver = driver;
}
/**
* Set the DB connection url.
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Set the user name for the DB connection.
*/
public void setUserid(String userId) {
this.userId = userId;
}
/**
* Set the password for the DB connection.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Gets the Operations.
*/
public List getOperations () {
return operations;
}
/**
* Adds an Operation.
*/
public void addOperation(Operation operation) {
operations.add(operation);
}
/**
* Load the sql file and then execute it
*/
public void execute() throws BuildException {
if (driver == null) {
throw new BuildException("Driver attribute must be set!", location);
}
if (userId == null) {
throw new BuildException("User Id attribute must be set!", location);
}
if (password == null) {
throw new BuildException("Password attribute must be set!", location);
}
if (url == null) {
throw new BuildException("Url attribute must be set!", location);
}
if (operations.size() == 0) {
throw new BuildException("Must declare at least one operation in a <dbunit> task!");
}
Driver driverInstance = null;
// Load the driver using the
try {
Class dc;
log("Loading " + driver + " using system loader.", Project.MSG_VERBOSE);
dc = Class.forName(driver);
driverInstance = (Driver) dc.newInstance();
}catch(ClassNotFoundException e){
throw new BuildException("Class Not Found: JDBC driver " + driver + " could not be loaded", location);
}catch(IllegalAccessException e){
throw new BuildException("Illegal Access: JDBC driver " + driver + " could not be loaded", location);
}catch(InstantiationException e) {
throw new BuildException("Instantiation Exception: JDBC driver " + driver + " could not be loaded", location);
}
try{
log("connecting to " + url, Project.MSG_VERBOSE );
Properties info = new Properties();
info.put("user", userId);
info.put("password", password);
conn = driverInstance.connect(url, info);
if (conn == null) {
// Driver doesn't understand the URL
throw new SQLException("No suitable Driver for " + url);
}
conn.setAutoCommit(true);
Iterator operIter = operations.listIterator();
while (operIter.hasNext()) {
Operation operation = (Operation)operIter.next();
operation.execute(conn);
}
} catch(DatabaseUnitException e){
throw new BuildException(e, location);
} catch(SQLException e){
throw new BuildException(e, location);
} finally {
try {
if (conn != null) {
conn.close();
}
}
catch (SQLException e) {}
}
}
}
--------------070303070901040003070607
Content-Type: text/plain;
name="DBUnitTaskTester.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="DBUnitTaskTester.java"
package com.insourcery.ant.dbunit;
import java.sql.SQLException;
import java.util.List;
import java.util.Hashtable;
import junit.framework.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.taskdefs.TaskdefsTest;
import org.dbunit.operation.DatabaseOperation;
/**
* Describe class <code>DBUnitTaskTester</code> here.
*
* @author "Ben Cox" <ben@bjtechnics.com>
* @version 1.0
* @since 1.0
* @see org.apache.tools.ant.taskdefs.TaskdefsTest
*/
public class DBUnitTaskTester extends TaskdefsTest {
protected static Class classUnderTest = DBUnitTaskTester.class;
public DBUnitTaskTester (String name) {
super(name);
}
public void setUp () {
configureProject("buildfile.xml");
}
public void testNoDriver () {
expectBuildException("no-driver", "Should have required a driver attribute.");
}
public void testNoDbUrl () {
expectBuildException("no-db-url", "Should have required a url attribute.");
}
public void testNoUserid () {
expectBuildException("no-userid", "Should have required a userid attribute.");
}
public void testNoPassword () {
expectBuildException("no-password", "Should have required a password attribute.");
}
public void testInvalidDatbaseInformation () {
Throwable sql = null;
try {
executeTarget("invalid-db-info");
} catch (BuildException e) {
sql = e.getException();
} finally {
assertNotNull("Should have thrown a SQLException.", sql);
assertTrue("Should have thrown a SQLException.", (sql instanceof SQLException));
}
}
public void testInvalidOperationType () {
Throwable iae = null;
try {
executeTarget("invalid-type");
} catch (BuildException e) {
iae = e.getException();
} finally {
assertNotNull("Should have thrown an IllegalArgumentException.", iae);
assertTrue("Should have thrown an IllegalArgumentException.", (iae instanceof IllegalArgumentException));
}
}
public void testResolveOperationTypes () {
assertOperationType("Should have been an DELETE_ALL operation",
"set-type-delete-all", DatabaseOperation.DELETE_ALL);
assertOperationType("Should have been an INSERT operation",
"set-type-insert", DatabaseOperation.INSERT);
assertOperationType("Should have been an UPDATE operation",
"set-type-update", DatabaseOperation.UPDATE);
assertOperationType("Should have been an REFRESH operation",
"set-type-refresh", DatabaseOperation.REFRESH);
assertOperationType("Should have been an DELETE operation",
"set-type-delete", DatabaseOperation.DELETE);
assertOperationType("Should have been an CLEAN_INSERT operation",
"set-type-clean-insert", DatabaseOperation.CLEAN_INSERT);
}
private void assertOperationType (String failMessage, String targetName, DatabaseOperation expected) {
Operation oper = getFirstOperFromTarget(targetName);
DatabaseOperation dbOper = oper.getDbOperation();
assertTrue(failMessage + ", but was: " + dbOper, expected.equals(dbOper));
}
private Operation getFirstOperFromTarget (String targetName) {
Operation result = null;
Hashtable targets = project.getTargets();
executeTarget(targetName);
Target target = (Target)targets.get(targetName);
DBUnitTask task = (DBUnitTask)target.getTasks()[0];
List operations = task.getOperations();
if (operations != null && operations.size() > 0) {
result = (Operation)operations.get(0);
} else {
fail("Can't get a dbunit <operation> from the target: " + targetName);
}
return result;
}
public static Test suite() {
TestSuite suite = new TestSuite(classUnderTest);
return suite;
}
public static void main(String args[]){
if (args.length > 0 && args[0].equals("-gui")) {
String[] testCaseName = {classUnderTest.getName()};
junit.swingui.TestRunner.main(testCaseName);
} else {
junit.textui.TestRunner.run(suite());
}
}
}
--------------070303070901040003070607
Content-Type: text/plain;
name="Operation.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Operation.java"
package com.insourcery.ant.dbunit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.operation.DatabaseOperation;
import org.dbunit.dataset.xml.FlatXmlDataSet;
public class Operation {
private String type;
private File src;
private DatabaseOperation dbOperation;
public Operation () {
this.type="CLEAN_INSERT";
}
public String getType () { return type; }
public File getSrc () { return src; }
public DatabaseOperation getDbOperation () { return dbOperation; }
public void setType (String type) {
this.type = type;
if ("UPDATE".equals(type)) {
dbOperation = DatabaseOperation.UPDATE;
} else if ("INSERT".equals(type)) {
dbOperation = DatabaseOperation.INSERT;
} else if ("REFRESH".equals(type)) {
dbOperation = DatabaseOperation.REFRESH;
} else if ("DELETE".equals(type)) {
dbOperation = DatabaseOperation.DELETE;
} else if ("DELETE_ALL".equals(type)) {
dbOperation = DatabaseOperation.DELETE_ALL;
} else if ("CLEAN_INSERT".equals(type)) {
dbOperation = DatabaseOperation.CLEAN_INSERT;
} else {
throw new IllegalArgumentException("Type must be one of: UPDATE, INSERT,"
+ " REFRESH, DELETE, DELETE_ALL, or CLEAN_INSERT,"
+ " but was: " + type);
}
}
public void setSrc (File src) {
this.src = src;
}
public void execute(Connection conn) throws DatabaseUnitException {
if (dbOperation != null) {
try {
DatabaseConnection dbConn = new DatabaseConnection(conn);
dbOperation.execute(dbConn, new FlatXmlDataSet(new FileInputStream(src)));
} catch (IOException e) {
throw new DatabaseUnitException(e);
} catch (SQLException e) {
throw new DatabaseUnitException(e);
}
} else {
throw new DatabaseUnitException ("Operation.execute(): setType(String) must be called before execute()!");
}
}
public String toString() {
StringBuffer result = new StringBuffer();
result.append("Operation: ");
result.append(" type=" + type);
result.append(", src=" + src.getAbsolutePath());
result.append(", dbOperation = " + dbOperation);
return result.toString();
}
}
--------------070303070901040003070607
Content-Type: text/xml;
name="buildfile.xml"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="buildfile.xml"
<?xml version="1.0"?>
<project name="ant-test" basedir="." default="all">
<taskdef name="dbunit" classname="com.supplywindows.ant.dbunit.DBUnitTask"/>
<target name="all" depends="no-driver, no-db-url, no-userid, no-password"/>
<target name="no-driver">
<dbunit url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="no-db-url">
<dbunit driver="org.gjt.mm.mysql.Driver"
userid="root" password="">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="no-userid">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
password="">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="no-password">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="invalid-db-info">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:foobar://localhost/dbunittest"
userid="root" password="">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="set-type-insert">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="set-type-update">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="UPDATE" src="pktest.xml"/>
</dbunit>
</target>
<target name="set-type-refresh">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="REFRESH" src="pktest.xml"/>
</dbunit>
</target>
<target name="set-type-delete">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="DELETE" src="pktest.xml"/>
</dbunit>
</target>
<target name="set-type-delete-all">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="DELETE_ALL" src="pktest.xml"/>
</dbunit>
</target>
<target name="set-type-clean-insert">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
</dbunit>
</target>
<target name="invalid-type">
<dbunit driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost/dbunittest"
userid="root" password="">
<operation type="CLEAN_INSERT" src="pktest.xml"/>
<operation type="DELETE" src="pktest.xml"/>
<operation type="RIDICULOUS" src="pktest.xml"/>
</dbunit>
</target>
</project>
--------------070303070901040003070607
Content-Type: text/plain;
name="dbunit-database-builder"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="dbunit-database-builder"
drop database dbunittest;
create database dbunittest;
create table testtable1 (column1 varchar (25) primary key, column2 varchar (25));
create table testtable2 (column1 varchar (25) primary key, column2 varchar (25));
create table testtable3 (column1 bigint (25) primary key, column2 varchar (25));
--------------070303070901040003070607
Content-Type: text/plain;
name="pktabledef.sql"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="pktabledef.sql"
-- MySQL dump 8.21
--
-- Host: localhost Database: dbunittest
---------------------------------------------------------
-- Server version 3.23.49
--
-- Table structure for table 'pk_table'
--
CREATE TABLE pk_table (
pk0 varchar(25) NOT NULL default '',
pk1 varchar(20) default NULL,
PRIMARY KEY (pk0)
) TYPE=MyISAM;
--
-- Dumping data for table 'pk_table'
--
INSERT INTO pk_table VALUES ('1','11');
--------------070303070901040003070607
Content-Type: text/xml;
name="pktest.xml"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="pktest.xml"
<!-- edited with XML Spy v3.5 (http://www.xmlspy.com) by () -->
<dataset>
<pk_table pk0="1" pk1="11"
pk0="3" pk1="33"/>
</dataset>
--------------070303070901040003070607--