Ôںܶà³É¹¦µÄÈí¼þÏîÄ¿ÖУ¬²âÊÔ×Ô¶¯»¯ÍùÍùÊǹؼüµÄ²ãÃæ¡£DBUnitÔÊÐí¿ª·¢ÈËÔ±ÔÚ²âÊÔ֮ǰ¸øÄ¿±êÊý¾Ý¿âÖ²Èë²âÊÔÊý¾Ý£¬ÔÚ²âÊÔÍê±Ïºó£¬ÔÙ½«Êý¾Ý¿â»Ö¸´µ½²âÊÔǰµÄ״̬¡£ÔÚ×î½üµÄÒ»¸öÏîÄ¿ÖУ¬ÎÒ³¢ÊÔʹÓÃÓÃDBUnit¶ÔSpring+iBatisµÄ¼Ü¹¹½øÐвâÊÔ£¬ÏÂÃæ¼Ç¼ÁËDBUnitµÄʹÓùý³ÌºÍÓöµ½µÄһЩÎÊÌâ¡£
²âÊÔ»·¾³
Ê×ÏÈ£¬ÎÒÃǽ¨Á¢Ò»¸ö²âÊÔ»·¾³£¨»ùÓÚMaven 2ºÍOracleÊý¾Ý¿â*£©¡£Êý¾Ý±íÃûAccount¡£
Êý¾Ý¿â
ÏȽ¨Á¢Ò»¸ö²âÊÔÊý¾Ý±í£¨Êý¾Ý¿âΪOracle*£©
Account.sql
CREATE TABLE Account ("ID" NUMBER, "USERNAME" VARCHAR2(256 BYTE) NOT NULL ENABLE, "PASSWORD" VARCHAR2(256 BYTE), CONSTRAINT "ACCOUNT_UK_ID" UNIQUE ("ID"), CONSTRAINT "ACCOUNT_PK" PRIMARY KEY ("USERNAME") ) |
ÕâÀïÎÒÔÝʱ²»ÏëÉæ¼°Sequence£¬ËùÒÔÖ÷¼ü**ÊÇusername£¬¶ø²»ÊÇID£¬²¢ÇÒIDÔÊÐíΪNULL¡£ÕâÊÇÒòΪSequenceµÄµÝÔöÊDz»¿É»Ö¸´µÄ£¬Èç¹ûÏîÄ¿¶Ô¼Ç¼IDÊÇ·ñÁ¬Ðø²»ÊÇÌØ±ðÔÚÒâµÄ»°£¬¿ÉÒÔÔÚ×Ô¼ºµÄÏîÄ¿Öн¨Á¢£¬Ö»ÒªÉÔ΢ÐÞ¸ÄÒ»ÏÂiBatisÅäÖÃÎļþÖеÄSQLÓï¾ä¾Í¿ÉÒÔÁË¡£ÕâÀïÎÒÃÇÏÈÆÁ±ÎÕâ¸öÎÊÌâ¡£
DBUnit²âÊÔOracleÊý¾Ý¿âʱ£¬ÕÊ»§×îºÃ²»ÒªÓµÓÐDBAȨÏÞ£¬·ñÔò»á³öÏÖorg.dbunit.database.AmbiguousTableNameException:
COUNTRIES ´íÎó¡£Èç¹ûÕÊ»§±ØÐë¾ß±¸DBAȨÏÞ£¬ÄÇô¾ÍÐèÒªÔÚÖ´ÐÐnew DatabaseConnectionʱ£¬Ã÷È·¸ø¶¨SCHEMA£¨Ãû³Æ±ØÐë´óд£©£¬Ïêϸ˵Ã÷²Î¿¼ÏÂÎĶദ´úÂë×¢Êͺ͡°org.dbunit.database.AmbiguousTableNameExceptionÒì³£¡±Õ½ڡ£
±í±ØÐë´æÔÚÖ÷¼ü£¬·ñÔò·µ»Øorg.dbunit.dataset.NoPrimaryKeyException´íÎó¡£
SpringÅäÖÃÎļþ
ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="${database.connection.driver_class}"/>
<property name="url" value="${database.connection.url}"/>
<property name="username" value="${database.connection.username}"/>
<property name="password" value="${database.connection.password}"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountManager" class="com.wang.dbunit.AccountManager">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
</beans> |
database.properties database.connection.driver_class=oracle.jdbc.driver.OracleDriver database.connection.url=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:test database.connection.username=username database.connection.password=password |
iBatisÅäÖÃÎļþ
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMapConfig PUBLIC"-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <settings useStatementNamespaces="false" cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" maxRequests="32" maxSessions="10" maxTransactions="5" /> <sqlMap resource="Account.xml"/> </sqlMapConfig> |
Account.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPEsqlMap PUBLIC"-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"> <sqlMap namespace="Account"> <resultMap id="accountMap" class="com.wang.dbunit.Account"> <result property="id" column="id" jdbcType="NUMBER" nullValue="0"/> <result property="userName" column="username" jdbcType="VARCHAR2"/> <result property="password" column="password" jdbcType="VARCHAR2"/> </resultMap> <!--** preserve ************************************** --> <sql id="id-select"> <![CDATA[ SELECT id_sequence.nextval AS id FROM dual ]]> </sql> <!--*************************************************** --> <sql id="account-select"> <![CDATA[ SELECTid, username ]]> <dynamic prepend=","> <isEqual property="includePassword" compareValue="true"> password </isEqual> </dynamic> FROMaccount </sql> <sql id="account-where"> <![CDATA[ username=#userName:VARCHAR2# ]]> <dynamic> <isNotNull property="password" prepend="AND "> <![CDATA[ password=#password:VARCHAR2# ]]> </isNotNull> </dynamic> </sql> <select id="getAccount" parameterClass="com.wang.dbunit.Account" resultMap="accountMap"> <include refid="account-select"/> <dynamic prepend=" WHERE"> <isNotNull property="userName"> <include refid="account-where"/> </isNotNull> </dynamic> </select> <!--**************************************************** --> <sql id="account-insert"> <![CDATA[ INSERT INTO account(username, password ]]> <dynamic prepend=","> <isNotEqual property="id" compareValue="0"> <![CDATA[ id ]]> </isNotEqual> </dynamic> ) </sql>
<sql id="account-insert-values">
<![CDATA[
VALUES(#userName:VARCHAR2#, #password:VARCHAR2#
]]>
<dynamic prepend=",">
<isNotEqual
property="id"
compareValue="0">
<![CDATA[
#id:NUMBER#
]]>
</isNotEqual>
</dynamic>
)
</sql>
<insert id="createAccount"
parameterClass="com.wang.dbunit.Account">
<isEqual
property="generateIdFromSequence"
compareValue="true">
<include refid="id-select"/>
</isEqual>
<include refid="account-insert"/>
<include refid="account-insert-values"/>
</insert>
</sqlMap> |
£¨Õâ¸öÅäÖÃÎļþÖÐÔ¤ÁôÁËδÀ´Ê¹Óà sequence µÄ¿ÉÄÜ£©
DBUnitÅäÖÃÎļþ
ÎÒÃÇͨ¹ýÒ»¸öxmlÖÖ×ÓÎļþ(seedfile)ΪDBUnitÌṩ²âÊÔÊý¾Ý£¬ÎļþÖеÄÊý¾Ý»á±»DBUnitÔÚ²âÊÔ¿ªÊ¼Ç°×Ô¶¯Ö²ÈëÊý¾Ý±í£¬Õâ¸öÎļþ½á¹¹ºÜ¼òµ¥£º
dataSet.xml
<?xml version='1.0' encoding='UTF-8'?> <DATASET> <ACCOUNT id='1' username='Drew' password='Smith'/> <ACCOUNT id='2' username='Nick' password='Marquiss'/> <ACCOUNT id='3' username='Jose' password='Whitson'/> </DATASET> |
¡°ACCOUNT¡±¾ÍÊDZíÃû³Æ£¬ËüµÄÊôÐÔ¾ÍÊÇ×Ö¶ÎÄÚÈÝ¡£
´úÂë
¸¨ÖúÀàAccout.java
package com.wang.dbunit; public class Account { private boolean generateIdFromSequence=false; private boolean includePassword = false; private long id = 0; private String userName = null; private String password = null; public boolean getGenerateIdFromSequence() { return generateIdFromSequence; } public void setGenerateIdFromSequence(boolean generateIdFromSequence) { this.generateIdFromSequence =generateIdFromSequence; } public void setId(long id) { this.id =id; } public long getId() { return this.id; } public String getPassword() { return password; } public void setPassword(String password) { this.password =password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName =userName; } public boolean isIncludePassword() { return includePassword; } public void setIncludePassword(boolean includePassword) { this.includePassword =includePassword; } } |
ÒµÎñÀàAccountManager.java
package com.wang.dbunit; import com.ibatis.sqlmap.client.SqlMapClient; public class AccountManager { protected SqlMapClient sqlMap = null; public void setSqlMapClient(SqlMapClient sqlMapClient) { this.sqlMap =sqlMapClient; } public Account getAccount(String userName, String password, boolean includePassword) throws Exception { Account account = new Account(); account.setUserName(userName); account.setPassword(password); account.setIncludePassword(includePassword); Account ret = (Account)(sqlMap.queryForObject("getAccount", account)); return ret; } public void createAccount(String userName, String password) throws Exception { Account account = new Account(); account.setUserName(userName); account.setPassword(password); sqlMap.insert("createAccount",account); } } |
ºÃÁË£¬ÎÒÃÇÍê³ÉÁËÁËÈ«²¿²âÊÔ»·¾³£¬½ÓÏÂÀ´ÎÒÃÇÒª¿ªÊ¼±àд²âÊÔÓÃÀý¡£
²âÊÔ
DatabaseTestCaseÀà
DBUnitÌṩÁËÒ»¸ö³éÏóÀࣺ DatabaseTestCase£¬Ëü¼Ì³Ð×Ô JUnitµÄ TestCase£¬Õâ¸öÀàÓÐÁ½¸ö·½·¨ÐèÒªÖØÔØ£º
protecte abstract IDatabaseConnection getConnection() throws Exception; protected abstract IDataSet getDataSet() throws Exception; |
getConnectionÓÃÓÚ¸æËß²âÊÔÓÃÀýÈçºÎÕÒµ½Êý¾Ý¿âÁ¬½Ó£»getDataSetÓÃÓÚ¸æËß²âÊÔÓÃÀýÈçºÎ»ñÈ¡²âÊÔÊý¾ÝÎļþ£¨dataSet.xml£©¡£ÏÂÃæÎÒÃÇÏȼ̳ÐÕâ¸ö³éÏóÀà±àд²âÊÔÓÃÀý£º
package com.wang.dbunit; import java.io.FileInputStream; import java.sql.Connection; import java.util.Properties; import javax.sql.DataSource; import com.wang.dbunit.Account; import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.dbunit.DatabaseTestCase; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.operation.DatabaseOperation; public class HelloDBUnit extends DatabaseTestCase { static Logger logger = LogManager.getLogger(HelloDBUnit.class.getName()); privatestatic ApplicationContext context; protected Properties props = new Properties(); public HelloDBUnit() throws IOException { super(); props.load(Resources.getResourceAsStream( "database.properties")); context = newClassPathXmlApplicationContext( "classpath:ApplicationContext.xml"); } //////////////////////////////////////////////// @Override protected IDatabaseConnection getConnection() throws Exception { DataSourcedataSource = (DataSource)context.getBean("dataSource"); Connectionconnection = dataSource.getConnection(); // Èç¹ûËùÓòâÊÔÕÊ»§ÊÇ DBA£¬ÎªÁ˱ÜÃâ³öÏÖ AmbiguousTableNameException // Òì³££¬ÏÂÃæ±ØÐë¸ÄдΪ newDatabaseConnection(connection, SCHEMA) // ÐÎʽ¡£×¢ÒâSCHEMA Òª´óд** return new DatabaseConnection(connection); } @Override protected IDataSet getDataSet()throws Exception { return new FlatXmlDataSet( new FileInputStream("bin/dataSet.xml")); } /////////////////////////////////////////////// @Override protected DatabaseOperation getSetUpOperation() throws Exception { return DatabaseOperation.REFRESH; } @Override protected DatabaseOperation getTearDownOperation() throws Exception { return DatabaseOperation.NONE; } //////////////////////////////////////////////////// public void testSelectAccount() { AccountManager manager = (AccountManager)context.getBean("accountManager"); try { Accountaccount = manager.getAccount("Nick", "Marquiss", true); assertNotNull(account); } catch (Exceptione) { logger.error(e.getMessage(),e); } } public void testCreateAccount() { AccountManager manager = (AccountManager)context.getBean("accountManager"); try { manager.createAccount("TEST", "test"); } catch(Exception e) { logger.error(e.getMessage(),e); } } } |
ÔÚgetConnection·½·¨ÖУ¬ÎÒÃÇͨ¹ýSpringÅäÖÃÎļþ»ñµÃÊý¾ÝÁ¬½Ó¡£
³ýÁËÇ°ÃæÄÇÁ½¸ö·½·¨Í⣬ÎÒÃÇ»¹ÖØÔØÁË getSetUpOperation ºÍ getTearDownOperation
·½·¨£ºDatabaseOperation.REFRESH ¸æËßDBUnitÔÚ²âÊÔ¿ªÊ¼Ç°±È½ÏÊý¾Ý¿âºÍÅäÖÃÎļþ£¬Èç¹û·¢ÏÖ²âÊÔÊý¾Ý²»´æ»ò²»Ò»ÖÂÔÚÔò²åÈë»ò¸üÐÂ***¡£DatabaseOperation.NONE±íʾʲôҲ²»×ö¡£
Õâ¸öCASEÓ¦¸Ã¿ÉÒÔÔËÐеĺܺ㬵«ÊÇÈç¹ûÎÒÃÇ°Ñ getTearDownOperation¸Ä³É£º
@Override protected DatabaseOperation getTearDownOperation() throws Exception { return DatabaseOperation.DELETE_ALL; } |
¾Í»á·¢Éújava.sql.SQLException: Closed ConnectionÒì³£¡£ÕâÊÇÎªÊ²Ã´ÄØ£¿ÎÊÌâ³öÔÚDatabaseTestCaseÖС£
²ÎÊýº¬Òå
DatabaseOperation.CLEAN_INSERT; ÏÈɾ³ý±íÖÐËùÓУ¬ÔÙ²åÈë×¼±¸µÄÊý¾Ý
DatabaseOperation.REFRESH; ʹÓÃ×¼±¸Êý¾Ý¸üÐÂ±í£¬´æÔÚÔòupdate£¬²»´æÔÚÔòinsert
DatabaseOperation.DELETE; ֻɾ³ý×¼±¸µÄÊý¾Ý
DatabaseOperation.DELETE_ALL Çå³ýËùÓмǼ
DatabaseOperation.NONE; ɶ¶¼²»×ö
java.sql.SQLException: Closed ConnectionÒì³£
À´¿´Ò»ÏÂDatabaseTestCaseµÄÒ»¸ö¹Ø¼ü³ÉÔ±±äÁ¿testerºÍÓйصÄһЩ·½·¨£º
public abstract class DatabaseTestCase extends TestCase { ...... private IDatabaseTester tester; ...... protected IDatabaseTester getDatabaseTester() throws Exception { if (this.tester == null) { this.tester = newDatabaseTester(); } return this.tester; } ...... protected IDatabaseTester newDatabaseTester() throws Exception{ logger.debug("newDatabaseTester()- start"); // ÖØÔØµÄ getConnection ·½·¨£¬ÔÚ IDatabaseTester ÀïÓÐÒ»¸öͬÃû·½·¨¡£ // ×¢ÒâÇø·Ö¡£ final IDatabaseConnection connection = getConnection(); final IDatabaseTester tester = new DefaultDatabaseTester(connection); return tester; } ...... protected void setUp() throws Exception { logger.debug("setUp()- start"); super.setUp(); final IDatabaseTester databaseTester = getDatabaseTester(); assertNotNull("DatabaseTesteris not set", databaseTester); databaseTester.setSetUpOperation(getSetUpOperation()); databaseTester.setDataSet(getDataSet()); databaseTester.onSetup(); } ...... } |
¿É¼û DatabaseTestCase ÄÚ²¿ÓÐÒ»¸ö IDatabaseTester ½Ó¿ÚµÄʵÀý£¨tester£©£¬Êµ¼ÊÉÏËùÓеIJâÊÔ¹¤×÷ÊÇÓÉËüÍê³ÉµÄ¡£¶øDatabaseTestCaseµÄnewDatabaseTester·½·¨ÔÚÉú³ÉÕâ¸öʵÀýµÄʱºòÓõÄÊÇDefaultDatabaseTester¡£´«ÈëÒ»¸öÓÉÖØÔØµÄgetConnection·½·¨·µ»ØµÄIDatabaseConnectionʵÀý¡£
DefaultDatabaseTester¼Ç¼ÁËÕâ¸öÁ¬½ÓʵÀýºó£¬ÌṩÁËÒ»¸öͬÃûµÄgetConnection()·½·¨£¨²»ÊÇDatabaseTestCaseÖб»ÖØÔصÄÄǸögetConnection£©£¬ÓÃÀ´·µ»ØËü£º
public class DefaultDatabaseTester extends AbstractDatabaseTester { final IDatabaseConnection connection; public DefaultDatabaseTester(final IDatabaseConnection connection){ this.connection= connection; } public IDatabaseConnection getConnection() throws Exception { return this.connection; } } |
ÒòΪËùÓеÄIDatabaseTesterʵÏÖ£¨°üÀ¨DefaultDatabaseTester£©¶¼¼Ì³Ð×ÔAbatractDatabaseTester£¬Õâ¸ö³éÏóÀàÓÐÒ»¸öͳһµÄÖ´ÐÐÊý¾Ý¿â²Ù×÷µÄ·½·¨executeOperation£¬Ô´úÂëÈçÏ£º
private void executeOperation(DatabaseOperation operation) throws Exception { logger.debug("executeOperation(operation={})- start", operation); if(operation != DatabaseOperation.NONE ){ // IDatabaseTester µÄ getConnection ·½·¨£¬²»ÊÇÖØÔØµÄÄǸö¡£ IDatabaseConnection connection = getConnection(); try{ operation.execute(connection, getDataSet() ); } finally{ closeConnection(connection); } } } |
ÎÒÃÇ¿´µ½Ã¿Ö´ÐÐÍêÒ»´Î²Ù×÷£¬Êý¾Ý¿âÁ¬½Ó¶¼»á±»¹Ø±Õ£¬ËùÒÔÈç¹û¼Ì³ÐDefaultDatabaseTester£¬½«µ¼ÖÂÖ»ÄÜÖ´ÐÐÒ»´ÎÊý¾Ý¿â²Ù×÷¡£
Èç¹ûÏ£ÍûÔÚÒ»¸öTestCaseÀïÖ´ÐÐÁ½´Î²Ù×÷£¬ÎÒÃÇ¿ÉÒÔʹÓÃÁíÒ»¸ö»ùÀà
DBTestCaseÀà
ÈçÉÏÃæËù¿´µ½µÄ£¬ÎÊÌâ³öÔÚDatabaseTestCaseµÄnewDatabaseTester·½·¨·µ»ØÁËÒ»¸öÎÞ·¨Öظ´ÀûÓõÄDefaultDatabaseTesterʵÀý£¬ËùÒÔDBTestCaseµÄnewDatabaseTester·½·¨´úÂë±ä¸üÈçÏ£º
protected IDatabaseTester newDatabaseTester() throws Exception { return new PropertiesBasedJdbcDatabaseTester(); } |
ËüÓÃÀ´Éú³ÉʵÀýµÄÊÇ PropertiesBasedJdbcDatabaseTester À࣬¶ø²»ÊÇ DefaultDatabaseTester
¡£Õâ¸öÀàµÄ¸¸Àà JdbcDatabaseTester£¨Ò²¼Ì³Ð×Ô AbstractDatabaseTester£©µÄ
getConnection ·½·¨£º
public IDatabaseConnection getConnection() throws Exception { logger.debug("getConnection() - start"); if(!initialized ){ // ×¢ÒâÕâ¸ö·½·¨£¬µÈÒ»ÏÂÏê½â initialize(); } assertNotNullNorEmpty("connectionUrl", connectionUrl); Connection conn = null; if(username == null && password == null ){ conn = DriverManager.getConnection(connectionUrl); }else{ Conn = DriverManager.getConnection(connectionUrl,username,password); } return new DatabaseConnection( conn, getSchema() ); } |
¿ÉÒÔ¿´µ½Ã¿´Îµ÷ÓÃÕâ¸ö·½·¨£¬¶¼»áн¨Ò»¸öÁ¬½Ó£¬¶ø²»ÊǼòµ¥µÄ·µ»ØÎÒÃÇÖØÔØµÄ getConnection Öзµ»ØµÄÁ¬½ÓµÄÒýÓá£ÕâÑù¾Í±ÜÃâÁË
DefaultDatabaseTester ½ö½öÊǼòµ¥·µ»ØÖ®Ç°µÄÁ¬½Ó¶øµ¹ÖõÄÎÊÌâ¡£²»¹ýÕâÒ²Òâζ×ÅÓà DBTestCase
¾Í²»ÓÃÎÒÃÇ×Ô¼ºÈ¥ÖØÔØ getConnection ÁË£¬ÒòΪ DBTestCase ÒѾʵÏÖÁËÕâ¸ö·½·¨£¨DatabaseTestCaseûÓÐʵÏÖ£©£º
protected IDatabaseConnection getConnection() throws Exception { logger.debug("getConnection() - start"); final IDatabaseTester databaseTester = getDatabaseTester(); assertNotNull( "DatabaseTester is not set",databaseTester); return databaseTester.getConnection(); } |
ÎÒÃÇ¿´µ½DBTestCaseµÄgetConnection¼òµ¥µÄ°ÑÕâ¸ö·½·¨×ª¸øJdbcDatabaseTester£¨IDatabaseTester£©
µÄgetConnection¡£¶øJdbcDatabaseTesterµÄʵÏÖÎÒÃÇÔÚÇ°ÃæÒѾ¿´µ½ÁË¡£
ÏÖÔÚÎÒÃǰÑDatabaseTestCaseÌæ»»³ÉDBTestCase£¬²¢ÇÒ×¢Ê͵ôHelloDBUnitÖÐÖØÔØµÄgetConnection£¨²»ÔÙÐèÒªÁË£¬¸¸ÀàDBTestCaseÖÐÒѾʵÏÖÁ˸÷½·¨¡££©È»ºóÖ´ÐУ¬ÎÒÃÇÓÖÓöµ½Ò»¸öÒì³££º
org.dbunit.AbstractDatabaseTester$AssertionFailedError:driverClass is null |
ÕâÊÇÒòΪPropertiesBasedJdbcDatabaseTesterµÄinitialize·½·¨£¨¼ûÉÏÃæ´úÂ룩ÓÃÀ´³õʼ»¯Êý¾Ý¿âÁ¬½Ó²ÎÊý£º
protected void initialize() throwsException { logger.debug("initialize() - start"); setDriverClass(System.getProperty(DRIVER_CLASS)); setConnectionUrl(System.getProperty(CONNECTION_URL)); setUsername(System.getProperty(USERNAME)); setPassword(System.getProperty(PASSWORD)); // Èç¹ûËùÓòâÊÔÕÊ»§ÊÇ DBA£¬ÎªÁ˱ÜÃâ³öÏÖ AmbiguousTableNameException // Òì³££¬±ØÐëÃ÷È·¸ø³ö SCHEMA¡£×¢Òâ SCHEMAÒª´óд** // setSchema(System.getProperty(SCHEMA)); super.initialize(); } |
´ÓÕâÀïÎÒÃÇ¿´µ½DBTestCaseÐèÒª´Óϵͳ±äÁ¿ÖлñµÃÁ¬½Ó²ÎÊý£¬ËùÒÔÎÒÃDZØÐëÐÞ¸ÄHelloDBUnitµÄ¹¹Ô캯Êý£¬½«ÅäÖòÎÊý¶ÁÈëϵͳ±äÁ¿£º
public HelloDBUnit() throws IOException { super(); props.load(Resources.getResourceAsStream("database.properties")); if(null == context) { context = new ClassPathXmlApplicationContext( "classpath:ApplicationContext.xml"); } System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, props.getProperty("database.connection.driver_class")); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, props.getProperty("database.connection.url")); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, props.getProperty("database.connection.username")); System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, props.getProperty("database.connection.password")); } |
ÏÖÔÚ¿ÉÒÔÕýÈ·Ö´ÐÐÁË¡£²»¹ý£¬ÕâÒÀÈ»´æÔÚÒź¶£¬¼ÈÈ»ÎÒÃÇʹËùÓÐÅäÖòÎÊý¶¼Îı¾»¯ÁË£¬¾Í²»Ï£Íû¿´µ½
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, props.getProperty("database.connection.driver_class")); |
ÕâÑùµÄ´úÂ룬ÒòΪÈç¹ûÎÒÃÇÓжà¸öÊý¾ÝÔ´£¬»ò¸Ä±äÁËÅäÖÃÎļþ£¬ÎÒÃDz»µÃ²»»¹ÐèÒª¸Ä±ä²âÊÔÓÃÀýµÄ´úÂë¡£¿ÉÒÔÓÃDataSourceBasedDBTestCase
À´½â¾öÕâ¸öÎÊÌâ¡£
DataSourceBasedDBTestCaseÀà DataSourceBasedDBTestCase
³éÏóÀàÒªÇó×ÓÀàʵÏÖ getDataSource ·½·¨ÒÔ»ñÈ¡ÍⲿÊý¾ÝÔ´¡£
Ê×ÏÈ£¬¸Ä±ä¸¸ÀàΪ DataSourceBasedDBTestCase ¡£È»ºóÒÆ³ý¹¹Ô캯ÊýÖйØÓÚϵͳ±äÁ¿µÄÉèÖá£×îºó¼ÓÈëÒÔÏ´úÂ룺
@Override protected DataSource getDataSource(){ return(DataSource)context.getBean("dataSource"); } |
org.dbunit.database.AmbiguousTableNameExceptionÒì³£
ºÜÒź¶£¬ DataSourceBasedDBTestCase ûÓÐÌṩÉèÖà SCHEMA µÄ·½·¨£¬ËäÈ»ËüµÄ³ÉÔ±±äÁ¿
DataSourceBasedDBTester ͨ¹ý¼Ì³ÐÁË AbstractDatabaseTester
¶øÌṩÁË setSchema ·½·¨£¬µ«ÊÇÒòΪËùÓÐµÄ IDatabaseTester ¶¼ÊÇ Private
±äÁ¿£¬Òò´Ëʵ¼ÊÉÏÎÒÃÇÎÞ·¨·ÃÎʵ½ËüµÄ setSchema¡£ËùÒÔÈç¹ûʹÓà DataSourceBasedDBTestCase
£¬³ý·ÇÖØÔØ setUp ºÍtearDown·½·¨£¬·ñÔò¾Í²»ÄÜÓÐDBAȨÏÞ¡£
protected void setUp() throws Exception { DataSource dataSource = getDataSource(); Connection connection = dataSource.getConnection(); IDatabaseConnection dbUnitCon = new DatabaseConnection(connection, "SYSTEM"); if(getDataSet() != null) { try { getSetUpOperation().execute(dbUnitCon, getDataSet()); } finally { if(connection!= null) connection.close(); } } } protected void tearDown() throws Exception { DataSource dataSource = getDataSource(); Connection connection = dataSource.getConnection(); IDatabaseConnection dbUnitCon = new DatabaseConnection(connection, "SYSTEM"); if(getDataSet()!= null) { try { getTearDownOperation().execute(dbUnitCon,getDataSet()); } finally { if(connection!= null) connection.close(); } } } |
Ö§³ÖÊÂÎñ»Ø¹ö
ËäÈ»DBUnitÌṩÁËһЩ·½·¨ÈÃÎÒÃÇ¿ÉÒÔÔÚ²âÊÔ¿ªÊ¼ºÍ½áÊøÊ±ÇåÀíÊý¾Ý¿â£¬µ«ÊÇÓÐʱºòÒÀÈ»²»ÄÜÂú×ãÐèÇ󣬱ÈÈçÔÚÉÏÃæµÄ´úÂëÖУ¬ÎÒÃÇÔÚÖ´Ðн׶βåÈëÁËÒ»Ìõ¼Ç¼£¨¼ûtestCreateAccount·½·¨£©£¬ÕâÖÖ²»ÊÇÔÚÖÖ×ÓÎļþÖеĶîÍâÊý¾Ý£¬²âÊÔ½áÊøºó³ý·ÇÔÚtearDownÖзµ»ØDatabaseOperation.DELETE_ALL£¬·ñÔòÊDz»»á±»×Ô¶¯É¾³ýµÄ£¬¿ÉÊÇÈç¹ûɾ³ýÈ«²¿Êý¾Ý£¬ÄÇôÓÖÓпÉÄÜɾµôÁ˲»Ï£ÍûɾµôµÄÊý¾Ý¡£SpringÌṩÁËÒ»¸öAbstractTransactionalDataSourceSpringContextTests²âÊÔÀ࣬Õâ¸öÀà¿ÉÒÔÔÚ²âÊÔ½áÊøºó»Ø¹öÊý¾Ý¿â£¬¿ÉÊÇDBUnitûÓÐÌṩÀàËÆµÄ»úÖÆ£¬ËùÒÔÎÒÃÇÒª½øÒ»²½ÊÖ¹¤À©Õ¹²âÊÔÓÃÀý£¬ÒÔ¼ÓÈëÀàËÆ¹¦ÄÜ¡£
ÐÞ¸ÄApplicationContext.xml
Ê×ÏÈ£¬ÐÞ¸ÄSpringµÄÅäÖÃÎļþApplicationContext.xml£¬¼ÓÈëÒÔÏÂÅäÖãº
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource"> <ref bean="dataSource"/> </property> </bean> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> |
Èç¹ûÏ£ÍûÒµÎñÀàÒ²Ö§³ÖÊÂÎñ´¦Àí¿ÉÒÔ¼ÓÈëÒÔÏÂÅäÖ㬷ñÔò¿ÉÒÔÂÔ¹ý£º
<bean id="accountManagerTarget" class="com.wang.dbunit.AccountManager"> <property name="sqlMapClient" ref="sqlMapClient"/> </bean> <bean id="accountManager" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value> com.wang.dbunit.IAccountManager </value> </property> <property name="interceptorNames"> <list> <idref local="transactionInterceptor" /> <idref local="accountManagerTarget" /> </list> </property> </bean> |
ÒÔÉÏÅäÖÃÖ»×÷ÓÃÓÚʹҵÎñÀ࣬ÒòΪÎÒÃǵIJâÊÔÓÃÀýÀà¡°HelloDBUnit.java¡±Ã»ÓгöÏÖÔÚÅäÖÃÎļþÖУ¬¸üûÓÐÉèÖÃÈκÎÀ¹½ØÆ÷£¬ËùÒÔ²âÊÔÓÃÀý¶ÔÊý¾Ý¿âµÄËùÓвÙ×÷£¨²åÈë¡¢Çå³ý²âÊÔÊý¾Ý£©Ä¿Ç°¶¼²»ÔÚÀ¹½Ø·¶Î§¡£ÎÒÃDZØÐëÔÚ²âÊÔÓÃÀýÖÐÊÖ¹¤ÎªËü¼ÓÈëÊÂÎñ´¦Àí£¬²Å¿ÉÒÔ´ïµ½ÎÒÃǵÄÄ¿µÄ¡£
Ìí¼ÓÊÂÎñ¹ÜÀí´úÂë
Ìí¼ÓÒÔÏÂÊôÐԺͷ½·¨£º
private TransactionStatus ts = null; private DataSourceTransactionManager transactionManager = null; ...... protected void setUpTransaction() { transactionManager =(DataSourceTransactionManager)context.getBean( "transactionManager"); TransactionDefinition td = new DefaultTransactionDefinition(); ts = transactionManager.getTransaction(td); } protected void tearDownTransaction(boolean commit) { if(commit) { transactionManager.commit(ts); } else { transactionManager.rollback(ts); } } |
ÐÞ¸ÄsetUpºÍtearDown·½·¨£º
protected void setUp() throws Exception { setUpTransaction(); DataSourced ataSource = getDataSource(); // Ìæ»» Connection connection = dataSource.getConnection(); Connection connection = DataSourceUtils.getConnection(dataSource); IDatabaseConnection dbUnitCon = new DatabaseConnection(connection, "SYSTEM"); if(getDataSet()!= null) { try { getSetUpOperation().execute(dbUnitCon, getDataSet()); } finally { if(connection!= null) { // Ìæ»» connection.close(); DataSourceUtils.releaseConnection( connection, dataSource); } } } } protected void tearDown() throws Exception { DataSource dataSource = getDataSource(); // Ìæ»» Connection connection = dataSource.getConnection(); Connection connection = DataSourceUtils.getConnection(dataSource); IDatabaseConnection dbUnitCon = new DatabaseConnection(connection, "SYSTEM"); if(getDataSet() != null) { try { // Èç¹û²»Ï£Íû»Ø¹öÊý¾Ý£¬´«Èë true ²ÎÊý¡£ tearDownTransaction(false); getTearDownOperation().execute(dbUnitCon, getDataSet()); } finally { if(connection!= null) { // Ìæ»» connection.close(); DataSourceUtils.releaseConnection( connection, dataSource); } } } } |
×îºóÐÞ¸ÄgetTearDownOperation£¬Óà DELETE Ìæ»» DELETE_ALL£º
protected DatabaseOperation getTearDownOperation() throws Exception { return DatabaseOperation.DELETE; } |
ÏÖÔÚÔÚ±íÖÐËæ±ãÌí¼ÓһЩ¼Ç¼£¬È»ºóÖ´ÐÐÎÒÃǵIJâÊÔÓÃÀý£¬Ö´ÐÐÍêºó£¬ÊÖ¹¤Ìí¼ÓµÄÊý¾ÝûÓÐÊܵ½ÈκÎÓ°Ïì¡£
×îºóÒ»µãÌáʾ:
ÒòΪÿһ¸ö testXxx ·½·¨Ê±¶¼»á³õʼ»¯Ò»¸ö²âÊÔÓÃÀý£¬ËùÒÔÿִÐÐÒ»´Î
testXxxx ·½·¨¶¼»áµ¼Ö setUp ºÍ tearDown ·½·¨±»µ÷ÓÃÒ»´Î£¬¶ø±¾ÀýµÄÊÂÎñ¶¨ÒåÒ²¶¼ÓÉ
setUp ¿ªÊ¼£¬ tearDown ½áÊø£¬Ò²¾ÍÒâζ×Ų»Í¬²âÊÔ·½·¨£¨Í¬Ò»²âÊÔÓÃÀý£©Ö®¼ä´¦ÓÚ²»Í¬µÄÊÂÎñ·¶Î§£¬µ¼ÖÂÊý¾Ý²Ù×÷½á¹ûÎÞ·¨¹²Ïí£¨Èç¹ûÿ´Î
tearDown ¶¼»Ø¹öÊý¾Ý£©¡£±ÈÈçÔÚ testInsert ·½·¨ÖвåÈëÊý¾Ý£¬ÔÚ testSelect
ÎÞ·¨»ñµÃ¡£Òª½â¾öÕâ¸öÎÊÌ⣬¾ÍÒªÊʵ±µÄÐÞ¸Ä¶Ô setUpTransaction ºÍ dearDownTransaction
µÄµ÷Óã¬Ê¹µÃÊÂÎñ¿ÉÒÔÔÚÈ«¾Ö·¶Î§ÄÚ±»¶à¸ö test ·½·¨¹²Ïí¡£
E:\work\bpm2_v1_00\test.xml:171: org.dbunit.dataset.NoSuchTableException:
VERSION_INFO
DBunit ÒªÇóschema ´óд
|