当前位置:Gxlcms > 数据库问题 > Spring Test Dbunit,H2数据库

Spring Test Dbunit,H2数据库

时间:2021-07-01 10:21:17 帮助过:10人阅读

       Spring Test DbUnit提供了Spring Test Framework与DBUnit之间的集成。使用Spring Test DbUnit提供了注解驱动的数据库集成测试方式。

       为了保证测试可模拟测试场景、可重复执行,我们需要一个简单容易的数据准备工具;一个隔离的干净的数据库环境。一般都是每次执行前都清掉数据库然后Dbunit(如果测试没有自己独立的库往往影响其他同事工作),测试完回滚到测试前的状态。所以这篇wiki后面会介绍内存数据库用于dbunit,这样就就可以保证每次测试时都可以有个相当干净的环境,而且不会影响其他人的开发。

      关于Dbunit的使用在网上可以搜索到很多文章,http://yangzb.iteye.com/blog/947292 写的很详细,所以这里不讨论DbUnit的使用,而是直接介绍Spring Test Dbunit的是使用。

Spring Test Dbunit配置和使用

1、项目中引入依赖

  1. <dependency>
  2. <groupId>com.github.springtestdbunit</groupId>
  3. <artifactId>spring-test-dbunit</artifactId>
  4. <version>1.2.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.dbunit</groupId>
  8. <artifactId>dbunit</artifactId>
  9. <version>2.5.0</version>
  10. </dependency>

2、注册Spring Test Dbunit监听器

定义一个测试的基类,其他的测试类集成这个基类,在积累上使用@TestExecutionListeners注解注册Spring Test Dbunit监听器,Spring Test DbUnit提供的注解就可以被Spring Test处理。

 

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration({ "classpath*:"classpath:applicationContext.xml" })
  3. @TestExecutionListeners({
  4. DbUnitTestExecutionListener.class,
  5. DirtiesContextTestExecutionListener.class,
  6. DependencyInjectionTestExecutionListener.class})
  7. @DbUnitConfiguration(databaseConnection = "h2DataSource")
  8. public class SpringTransactionalTestCase {
  9. @Test
  10.     public void testToString() throws Exception {
  11.     }
  12. }


3、数据源配置

       如果在Spring Test DbUnit中不配置其他的数据源默认使用Spring容器中id="dataSource"的数据源,Spring Test DbUnit支持配置多数据源。

  • 如果需要指定数据源,配置如下:
  1. <code> @DbUnitConfiguration(databaseConnection="h2DataSource")  //参见上面的SpringTransactionalTestCase类</code>
  1. applicationContext-mybatis-test.xml配置文件如下:
  1. <!--h2数据源-->
  2. <bean id="h2DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  3. <property name="driverClassName" value="org.h2.Driver" />
  4. <!-- where the db will be placed (created automatically) -->
  5. <property name="url" value="jdbc:h2:./db/test" />
  6. <property name="username" value="sa" />
  7. <property name="password" value="" />
  8. </bean>
  9. <!--主连接配置-->
  10. <bean id="h2SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  11. <property name="dataSource" ref="h2DataSource"/>
  12. <!-- 配置扫描Domain的包路径 -->
  13. <property name="typeAliasesPackage" value="com.and1.test.domain"/>
  14. <!-- 配置扫描Mapper XML的位置 -->
  15. <property name="mapperLocations" value="classpath*:com/and1/test/mapper/**/*.xml"/>
  16. <!-- 配置mybatis配置文件的位置 -->
  17. <property name="configLocation" value="classpath:mybatis-config.xml"/>
  18. <!-- 注册类型转换器 -->
  19. <property name="typeHandlers">
  20. <list>
  21. <ref bean="dateIntTypeHandler"></ref>
  22. </list>
  23. </property>
  24. </bean>
  25. <!-- 配置扫描Mapper接口的包路径 -->
  26. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  27. <property name="sqlSessionFactoryBeanName" value="h2SqlSessionFactory" />
  28. <property name="basePackage" value="com.and1.test.dao.mapper"/>
  29. </bean>
  30. <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
  31. <constructor-arg ref="h2SqlSessionFactory"/>
  32. </bean>

 

  • 如果需要配置多数据源(spring-test-dbunit 1.2.0之后的版本才可以配置多数据源),则配置如下
  1. <code>@DatabaseSetup</code><span style="color: #404040">, <code>@DatabaseTearDown</code><span style="color: #404040"> 和 <code>@ExpectedDatabase如果没有指定默认使用第一个第一个数据源(dataSource数据源),如需指定数据源,则如下:</code></span></span>

 

@DatabaseSetup(connection = "dataSource", value = "classpath:com/and1/test/service/deal/DealServiceTest.testSyncDB.setUp.xml")

4、Setup 和 TearDown

@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。

 

  1. public enum DatabaseOperation {
  2. //将数据集中的内容更新到数据库中。它假设数据库中已经有对应的记录,否则将失败。
  3. UPDATE,
  4. //将数据集中的内容插入到数据库中。它假设数据库中没有对应的记录,否则将失败。
  5. INSERT,
  6. //将数据集中的内容刷新到数据库中。如果数据库有对应的记录,则更新,没有则插入。
  7. REFRESH,
  8. //删除数据库中与数据集对应的记录。
  9. DELETE,
  10. //删除表中所有的记录,如果没有对应的表,则不受影响。
  11. DELETE_ALL,
  12. //与DELETE_ALL类似,更轻量级,不能rollback。
  13. TRUNCATE_TABLE,
  14. //是一个组合操作,是DELETE_ALL和INSERT的组合
  15. CLEAN_INSERT;
  16. }
 

DealMqMessageMapperTest.setUp.xml

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <dataset>
  3. <deal_mq_message id="1" deal_id="4234" created_time="2014-10-17 14:37:41"/>
  4. </dataset>
  1. <span style="color: #404040"><span style="color: #404040"> </span></span>

DealMqMessageMapperTest.expected.xml

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <dataset>
  3. <deal_mq_message id="1" deal_id="4234" />
  4. <deal_mq_message id="2" deal_id="123456" />
  5. </dataset>
  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration({ "classpath*:"classpath:applicationContext.xml" })
  3. @TestExecutionListeners({
  4. DbUnitTestExecutionListener.class,
  5. DirtiesContextTestExecutionListener.class,
  6. DependencyInjectionTestExecutionListener.class})
  7. @DbUnitConfiguration(databaseConnection = "h2DataSource")
  8. public class SpringTransactionalTestCase {
  1. <span style="font-family: Arial, Helvetica, sans-serif;">}</span>

 @DatabaseTearDown注解用来指定测试之后期望的数据库状态。可以加在方法上或者类上。这个注解非必须,默认是回滚@DatabaseSetup 和test method对数据的更改。

 

 

  1. value:数据集文件,<span style="color: #404040">测试<span style="color: #404040">之后根据这个数据集(DataSet)文件设置数据库的期望状态,是标准的DbUnit XML文件。</span></span>

 

connection:指定数据源,必须是@DbUnitConfiguration中配置的数据源,如果不指定,默认是@DbUnitConfiguration配置的第一个数据源。Spring-test-dbunit 1.2.0之后才支持。

type:对数据库的操作类型,如果不设置默认是DatabaseOperation.CLEAN_INSERT。比如我这里设置的是DatabaseOperation.DELETE,这个操作会删除DealMqMessageMapperTest.expected.xml里面的记录。

5、Expected results

  1. @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会执行两次。

H2数据库

1、依赖

  1. <dependency>
  2. <groupId>com.h2database</groupId>
  3. <artifactId>h2</artifactId>
  4. <version>1.4.184</version>
  5. </dependency>
  6. <!-- maven sql 插件 -->
  7. <plugin>
  8. <groupId>org.codehaus.mojo</groupId>
  9. <artifactId>sql-maven-plugin</artifactId>
  10. <version>1.5</version>
  11. <dependencies>
  12. <dependency>
  13. <groupId>com.h2database</groupId>
  14. <artifactId>h2</artifactId>
  15. <version>1.4.184</version>
  16. </dependency>
  17. </dependencies>
  18. <configuration>
  19. <driver>org.h2.Driver</driver>
  20. <url>jdbc:h2:./db/mtdc</url>
  21. <username>sa</username>
  22. <password></password>
  23. <skip>${maven.test.skip}</skip>
  24. <!--<srcFiles>-->
  25. <!--<srcFile>src/test/resources/dc.sql</srcFile>-->
  26. <!--</srcFiles>-->
  27. </configuration>
  28. <executions>
  29. <execution>
  30. <id>drop-table</id>
  31. <phase>process-test-resources</phase>
  32. <goals>
  33. <goal>execute</goal>
  34. </goals>
  35. <configuration>
  36. <url>jdbc:h2:./db/mtdc</url>
  37. <autocommit>true</autocommit>
  38. <srcFiles>
  39. <srcFile>src/test/resources/dc_drop_table.sql</srcFile>
  40. </srcFiles>
  41. <onError>continue</onError>
  42. </configuration>
  43. </execution>
  44. <execution>
  45. <id>create-table</id>
  46. <phase>process-test-resources</phase>
  47. <goals>
  48. <goal>execute</goal>
  49. </goals>
  50. <configuration>
  51. <url>jdbc:h2:./db/mtdc</url>
  52. <autocommit>true</autocommit>
  53. <srcFiles>
  54. <!--<srcFile>src/test/resources/dc_drop_table.sql</srcFile>-->
  55. <srcFile>src/test/resources/dc.sql</srcFile>
  56. </srcFiles>
  57. </configuration>
  58. </execution>
  59. </executions>

2、h2测试库的建表语句
  1. src/test/resources/dc_drop_table.sql),另一个是建表的sql(src/test/resources/dc.sql)。
  1. 不支持表级别comment
字段不支持 COLLATE utf8_bin 字段不支持CHARACTER SET utf8mb4 字段不支持CHARACTER SET utf8

3、sql-maven-plugin 插件

它通过Maven来执行配置好的数据库脚本,可以通过在POM中配置sql命令,或者将脚本写在文件中,在POM中配置文件位置。最后,运行 mvn sql:execute 以执行所有脚本。具体的配置参考上面的依赖。  

脚本插件包括以下步骤:

 
  1. 删除h2 中mtdc库中的所有表
  2. 创建表,索引等

当然我们可以根据具体情况裁剪这些步骤,比如,如果我们需要在一段时间内使用这个脚本创建的干净数据库环境,需要注意的是,执行很多DDL的时候我们一般需要最高的数据库权限。

4、数据源配置

参考spring test dbunit的数据源的配置。

总结

通过建一个Maven项目,使用 maven-sql-plugin 管理数据库脚本的执行,通过Spring test dbunit去实现数据库初始数据准备与还原,然后使用CI服务器来调用这个Maven项目,我们就可以实现基于Maven的实现数据库的持续集成测试了。

Spring Test Dbunit,H2数据库

标签:default   org   database   tab   关于   href   ber   stream   username   

人气教程排行