时间:2021-07-01 10:21:17 帮助过:6人阅读
Spring Test DbUnit提供了Spring Test Framework与DBUnit之间的集成。使用Spring Test DbUnit提供了注解驱动的数据库集成测试方式。
为了保证测试可模拟测试场景、可重复执行,我们需要一个简单容易的数据准备工具;一个隔离的干净的数据库环境。一般都是每次执行前都清掉数据库然后Dbunit(如果测试没有自己独立的库往往影响其他同事工作),测试完回滚到测试前的状态。所以这篇wiki后面会介绍内存数据库用于dbunit,这样就就可以保证每次测试时都可以有个相当干净的环境,而且不会影响其他人的开发。
关于Dbunit的使用在网上可以搜索到很多文章,http://yangzb.iteye.com/blog/947292 写的很详细,所以这里不讨论DbUnit的使用,而是直接介绍Spring Test Dbunit的是使用。
<dependency> <groupId>com.github.springtestdbunit</groupId> <artifactId>spring-test-dbunit</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.5.0</version> </dependency>
定义一个测试的基类,其他的测试类集成这个基类,在积累上使用@TestExecutionListeners注解注册Spring Test Dbunit监听器,Spring Test DbUnit提供的注解就可以被Spring Test处理。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath*:"classpath:applicationContext.xml" }) @TestExecutionListeners({ DbUnitTestExecutionListener.class, DirtiesContextTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) @DbUnitConfiguration(databaseConnection = "h2DataSource") public class SpringTransactionalTestCase { @Test public void testToString() throws Exception { } }
如果在Spring Test DbUnit中不配置其他的数据源默认使用Spring容器中id="dataSource"的数据源,Spring Test DbUnit支持配置多数据源。
@DbUnitConfiguration(databaseConnection="h2DataSource") //参见上面的SpringTransactionalTestCase类
h2DataSource数据源需要在注解
@ContextConfiguration中配置的applicationContext配置文件中声明,我这里是用个专门的applicationContext配置文件(src/test/resource/applicationContext-mybatis-test.xml,业务代码中数据源的配置文件是src/java/resource/applicationContext-mybatis.xml)声明数据源,并测试类的@ContextConfiguration中只加载applicationContext-mybatis-test.xml替换业务代码中的applicationContext-mybatis.xml。这样做的原因是为了集成测试环境使用独立的内存数据库。
applicationContext-mybatis-test.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="<a href="http://www.springframework.org/schema/beans" "="" style="text-decoration: none; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(0, 51, 102) !important; background: 0px 50%;">http://www.springframework.org/schema/beans" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance" "="" style="text-decoration: none; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(0, 51, 102) !important; background: 0px 50%;">http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans <a href="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" "="" style="text-decoration: none; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(0, 0, 0) !important; background: 0px 50%;">http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-lazy-init ="true"> <!--h2数据源--> <bean id="h2DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.h2.Driver" /> <!-- where the db will be placed (created automatically) --> <property name="url" value="jdbc:h2:./db/test" /> <property name="username" value="sa" /> <property name="password" value="" /> </bean> <!--主连接配置--> <bean id="h2SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="h2DataSource"/> <!-- 配置扫描Domain的包路径 --> <property name="typeAliasesPackage" value="com.and1.test.domain"/> <!-- 配置扫描Mapper XML的位置 --> <property name="mapperLocations" value="classpath*:com/and1/test/mapper/**/*.xml"/> <!-- 配置mybatis配置文件的位置 --> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- 注册类型转换器 --> <property name="typeHandlers"> <list> <ref bean="dateIntTypeHandler"></ref> </list> </property> </bean> <!-- 配置扫描Mapper接口的包路径 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="h2SqlSessionFactory" /> <property name="basePackage" value="com.and1.test.dao.mapper"/> </bean> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="h2SqlSessionFactory"/> </bean> </beans>
@DbUnitConfiguration(databaseConnection={"dataSource", "h2DataSource"})
@DatabaseSetup
, @DatabaseTearDown
和 @ExpectedDatabase如果没有指定默认使用第一个第一个数据源(dataSource数据源),如需指定数据源,则如下:
@DatabaseSetup(connection = "dataSource", value = "classpath:com/and1/test/service/deal/DealServiceTest.testSyncDB.setUp.xml")
@DatabaseSetup
注解用来测试之前配置数据库的初始状态, 这个注解可以放在整个测试类上或者单个测试方法上,如果放在类上,则对所有方法都有效。如果不需要准备初始数据,可以不用此注解。
@DatabaseSetup(value = "classpath:com/and1/test/dao/mapper/deal/DealMqMessageMapperTest.setUp.xml", connection = "h2DataSource", type = DatabaseOperation.CLEAN_INSERT)
value:数据集文件,测试执行之前设置数据库初始状态的数据集(DataSet)文件,是标准的DbUnit XML文件 (可以利用sequel pro的bundles实现生成xml文件:https://github.com/alsbury/SequelProCopyPHPUnitDataset)
connection:指定数据源,必须是@DbUnitConfiguration中配置的数据源,如果不指定,默认是@DbUnitConfiguration配置的第一个数据源。Spring-test-dbunit 1.2.0之后才支持。
type:对数据库的操作类型,如果不设置默认是DatabaseOperation.CLEAN_INSERT。
public enum DatabaseOperation { //将数据集中的内容更新到数据库中。它假设数据库中已经有对应的记录,否则将失败。 UPDATE, //将数据集中的内容插入到数据库中。它假设数据库中没有对应的记录,否则将失败。 INSERT, //将数据集中的内容刷新到数据库中。如果数据库有对应的记录,则更新,没有则插入。 REFRESH, //删除数据库中与数据集对应的记录。 DELETE, //删除表中所有的记录,如果没有对应的表,则不受影响。 DELETE_ALL, //与DELETE_ALL类似,更轻量级,不能rollback。 TRUNCATE_TABLE, //是一个组合操作,是DELETE_ALL和INSERT的组合 CLEAN_INSERT; }
DealMqMessageMapperTest.setUp.xml
<?xml version="1.0" encoding="UTF-8"?> <dataset> <deal_mq_message id="1" deal_id="4234" created_time="2014-10-17 14:37:41"/> </dataset>
DealMqMessageMapperTest.expected.xml
<?xml version="1.0" encoding="UTF-8"?> <dataset> <deal_mq_message id="1" deal_id="4234" /> <deal_mq_message id="2" deal_id="123456" /> </dataset>
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath*:"classpath:applicationContext.xml" }) @TestExecutionListeners({ DbUnitTestExecutionListener.class, DirtiesContextTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) @DbUnitConfiguration(databaseConnection = "h2DataSource") public class SpringTransactionalTestCase { <div class="line number4 index3 alt1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; margin: 0px; padding: 0px 1em 0px 0px; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; outline: 0px; overflow: visible; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; white-space: nowrap; background: 0px 50%;"><code class="java color1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(128, 128, 128) !important; background: 0px 50%;"> @Test</code></div><div class="line number5 index4 alt2" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; margin: 0px; padding: 0px 1em 0px 0px; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; outline: 0px; overflow: visible; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; white-space: nowrap; background: 0px 50%;"><code class="java spaces" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;"> </code><code class="java color1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(128, 128, 128) !important; background: 0px 50%;">@DatabaseSetup</code><code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">(value = </code><code class="java string" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(0, 51, 102) !important; background: 0px 50%;">"classpath:com/and1/test/dao/mapper/deal/DealMqMessageMapperTest.setUp.xml"</code><code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">)</code></div><div class="line number6 index5 alt1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; margin: 0px; padding: 0px 1em 0px 0px; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; outline: 0px; overflow: visible; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; white-space: nowrap; background: 0px 50%;"><code class="java spaces" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;"> </code><code class="java color1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(128, 128, 128) !important; background: 0px 50%;">@ExpectedDatabase</code><code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">(value = </code><code class="java string" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(0, 51, 102) !important; background: 0px 50%;">"classpath:<span style="color: rgb(0, 51, 102); font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; white-space: nowrap; background-color: rgb(240, 240, 240);">com/and1/test</span>/dao/mapper/deal/DealMqMessageMapperTest.expected.xml"</code><code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">, assertionMode = DatabaseAssertionMode.NON_STRICT)</code></div><div class="line number7 index6 alt2" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; margin: 0px; padding: 0px 1em 0px 0px; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; outline: 0px; overflow: visible; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; white-space: nowrap; background: 0px 50%;"><code class="java spaces" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;"> </code><code class="java color1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(128, 128, 128) !important; background: 0px 50%;">@DatabaseTearDown</code><code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">(value = </code><code class="java string" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; color: rgb(0, 51, 102) !important; background: 0px 50%;">"classpath:<span style="color: rgb(0, 51, 102); font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; white-space: nowrap; background-color: rgb(240, 240, 240);">com/and1/test</span>/dao/mapper/deal/DealMqMessageMapperTest.expected.xml"</code><code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">, type = DatabaseOperation.DELETE)</code></div><div class="line number8 index7 alt1" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 20px; margin: 0px; padding: 0px 1em 0px 0px; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; outline: 0px; overflow: visible; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; white-space: nowrap; background: 0px 50%;"><code class="java spaces" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;"> </code><code class="java keyword" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; font-weight: bold !important; color: rgb(51, 102, 153) !important; background: 0px 50%;">public</code> <code class="java keyword" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; font-weight: bold !important; color: rgb(51, 102, 153) !important; background: 0px 50%;">void</code> <code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">testInsert() </code><code class="java keyword" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; font-weight: bold !important; color: rgb(51, 102, 153) !important; background: 0px 50%;">throws</code> <code class="java plain" style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; border-radius: 0px; border: 0px; bottom: auto; float: none; height: auto; left: auto; margin: 0px; outline: 0px; overflow: visible; padding: 0px; position: static; right: auto; top: auto; vertical-align: baseline; width: auto; box-sizing: content-box; min-height: inherit; background: 0px 50%;">Exception {</code></div> } }
@DatabaseTearDown注解
用来指定测试之后期望的数据库状态。可以加在方法上或者类上。这个注解非必须,默认是回滚@DatabaseSetup 和test method对数据的更改。
@DatabaseTearDown(value = "classpath:com/and1/test/dao/mapper/deal/DealMqMessageMapperTest.expected.xml", type = DatabaseOperation.DELETE)
value:数据集文件,测试之后根据这个数据集(DataSet)文件设置数据库的期望状态,是标准的DbUnit XML文件。
connection:指定数据源,必须是@DbUnitConfiguration中配置的数据源,如果不指定,默认是@DbUnitConfiguration配置的第一个数据源。Spring-test-dbunit 1.2.0之后才支持。
type:对数据库的操作类型,如果不设置默认是DatabaseOperation.CLEAN_INSERT。比如我这里设置的是DatabaseOperation.DELETE,这个操作会删除DealMqMessageMapperTest.expected.xml里面的记录。
@ExpectedDatabase注解用来验证测试执行的结果,一般是用于insert 、update、delete等会发生数据改变的测试。这个注解可以作用于方法或者类上,如果作用于类上,是在这个类所有的测试方法执行完之后才执行。
@ExpectedDatabase(value = "classpath:com/and1/test/dao/mapper/deal/DealMqMessageMapperTest.expected.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
value:期望数据集的文件,测试之后用来和实际数据集进行断言验证。
connection:指定数据源,必须是@DbUnitConfiguration中配置的数据源,如果不指定,默认是@DbUnitConfiguration配置的第一个数据源。Spring-test-dbunit 1.2.0之后才支持。
assertionMode:测试结果和DataSet数据文件断言的类型。DatabaseAssertionMode.DEFAULT作为一个标准的DbUnit测试运行,执行一个完整的期望数据集和实际数据集的比对。DatabaseAssertionMode.NON_STRICT将忽略没有在期望数据集中出现,但是在实际数据集中出现的 表和列名。当集成测试执行在实际数据库包含很多有很多列的表中, 这将十分有用。我们不需要定义所有的这些,只需要我们感兴趣的表和列。
table:指定table去进行断言。
query:指定sql查询语句,检索实际数据集。必须要指定table,才能使用query。
Spring Test DbUnit的执行过程如下:
@DatabaseSetup -> Test Method执行 -> @ExpectedDatabase -> @DatabaseTearDown
6、事务配置
Spring Test框架本身提供的TransactionalTestExecutionListener和@Transactional增强后事务边界范围仅限于在测试方法Test Method内。Spring Teset DbUnit提供了 TransactionDbUnitTestExecutionListener会将事务边界扩大到Spring Test DbUnit执行的整个过程,事务在@DatabaseSetup注解开始,在@DatabaseTearDown和@ExpectedDatabase执行后结束。
@RunWith (SpringJUnit4ClassRunner. class )
@ContextConfiguration
@Transactional
@TestExecutionListeners ({
DependencyInjectionTestExecutionListener. class ,
DirtiesContextTestExecutionListener. class ,
TransactionDbUnitTestExecutionListener. class })
|
注意:这里不需要注册DbUnitTestExecutionListener.class,TransactionDbUnitTestExecutionListener 是对DbUnitTestExecutionListener 进行了事务增强,如果两者都配置的话@DatabaseSetup,@ExpectedDatabase,@DatabaseTearDown会执行两次。
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.184</version> </dependency> <!-- maven sql 插件 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sql-maven-plugin</artifactId> <version>1.5</version> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.184</version> </dependency> </dependencies> <configuration> <driver>org.h2.Driver</driver> <url>jdbc:h2:./db/mtdc</url> <username>sa</username> <password></password> <skip>${maven.test.skip}</skip> <!--<srcFiles>--> <!--<srcFile>src/test/resources/dc.sql</srcFile>--> <!--</srcFiles>--> </configuration> <executions> <execution> <id>drop-table</id> <phase>process-test-resources</phase> <goals> <goal>execute</goal> </goals> <configuration> <url>jdbc:h2:./db/mtdc</url> <autocommit>true</autocommit> <srcFiles> <srcFile>src/test/resources/dc_drop_table.sql</srcFile> </srcFiles> <onError>continue</onError> </configuration> </execution> <execution> <id>create-table</id> <phase>process-test-resources</phase> <goals> <goal>execute</goal> </goals> <configuration> <url>jdbc:h2:./db/mtdc</url> <autocommit>true</autocommit> <srcFiles> <!--<srcFile>src/test/resources/dc_drop_table.sql</srcFile>--> <srcFile>src/test/resources/dc.sql</srcFile> </srcFiles> </configuration> </execution> </executions>
因为h2数据库对mysql的ddl语句的语法不是完全支持,所以mtdc项目test目录下维护了两个sql文件,一个是每次测试前drop h2数据库的所有的表(
src/test/resources/dc_drop_table.sql),另一个是建表的sql(src/test/resources/dc.sql)。
目前我发现的一些不支持的情况不支持表级别comment 字段不支持 COLLATE utf8_bin 字段不支持CHARACTER SET utf8mb4 字段不支持CHARACTER SET utf8
脚本插件包括以下步骤:
当然我们可以根据具体情况裁剪这些步骤,比如,如果我们需要在一段时间内使用这个脚本创建的干净数据库环境,需要注意的是,执行很多DDL的时候我们一般需要最高的数据库权限。
通过建一个Maven项目,使用 maven-sql-plugin 管理数据库脚本的执行,通过Spring test dbunit去实现数据库初始数据准备与还原,然后使用CI服务器来调用这个Maven项目,我们就可以实现基于Maven的实现数据库的持续集成测试了。
http://springtestdbunit.github.io/spring-test-dbunit/
http://rockingware.com/2014/01/spring-test-dbunit.html
http://juvenshun.iteye.com/blog/207326
DbUnit实践:Spring Test Dbunit,H2数据库
标签: