SPring DBUnit 提供了spring测试框架和流行的DBunit项目的集成。通过简单的注解,它能让你设置和销毁数据库表,同时在测试完成时,检查符合预期的表的内容。
项目可以配置运行DBUnit测试通过使用Spring TestExecutionListener 或者使用一个JUnit @Rule.使用JUnit@Rule可以更容易配置但是只有在你使用JUnit4.7+才有效。
注意:本部分配置DBUnit测试,运行时使用Spring TestExecutionListener。如果你想使用JUnit @Rule配置DBUnit,看下一节。
为了让Sring处理DBUnit注解,你必须首先配置你的测试去使用DBUnitTestExecution类。你需要使用Spring @TestExecutionListeners 注解。一般来说,除了DBUnitTestExecutionListener,你同时需要包括标准Spring 监听器。下面是一个典型的JUnit4测试的注解。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })查看Spring javaDocs中关于标准监听器的介绍获取详细信息。
为了连接数据库,Spring DBUnit 需要一个bean 被注册到你的测试XML文件中。默认一个bean命名或者可以被使用(如果你需要其他的名字,查看高级配置小节)。bean 可以引用一个IDatabaseConnection或者更加典型的一个Java数据源。下面是一个典型的配置,连接超音速内存数据库。
当你配置了DbUnitTestExcutionListener,同时提供了连接数据库的bean,你就可以使用DBUnit注解了。
使用JUnit @Rule配置
注意:JUnit @Rule配置现在不能和Spring3.1工作,除非问题解决了,否则请使用TestExecutionListener。
本小节配置DBUnit 测试运行在JUnit4.7+@Rule。查看上面如果你希望配置DBUnit测试使用Spring TestExecutionListener.
为了让JUnit处理DBUnit注解,你必须配置你的测试使用DbUnitRule @Rule。为此你需要使用Junit@Rule注解,结合DbUnitRule类。
@Rule public DbUnitRule dbUnit = new DbUnitRule();你同时也需要确保你的测试类提供了获取数据源或者IDtabaseConnection的方法。你可以使用setDataSource或者setDatabaseConnection方法在规则上,或者更加通用的,注入一个数据源到一个测试类的私有的字段中。
@Autowired private DataSource dataSource;一旦你的规则定义好了你可以使用DBUnit注解了。
注意:在任何注解可以使用之前,你需要完成上面的配置小结步骤。没有合适的配置,DBUnit注解将被忽略。
@DatabaseSetup 和@DatabaseTearDown 注解用来在测试执行之前配置数据库表,在测试执行完成后重置它们。
@DatabaseSetup注解暗示了数据库表应该在方法运行之前设置。注解可以在单个测试方法或者整个类上起作用。
当作用到类的级别上时,设置在测试的每个方法上发生。注解的值引用了一个文件包含了可以重置数据库表的数据集。
典型的是一个标准的DBUnit XML文件,尽管它也可以加载自定义类型(看下面)。
下面是一个典型的设置注解。在本例中,一个和测试文件相同的包下面的名称为sampleData.xml的文件被引用了。
@DatabaseSetup("sampleData.xml")同时也可以引用特定位置的资源,例如:
@DatabaseSetup("/META-INF/dbtest/sampleData.xml")默认情况下设置将执行一个操作。这意味着从XML数据集中引用的表的所有的数据在被插入新的行之前将被删除。 通过使用类型属性,标准的DBUnit操作将被支持。看下面的JavaDocs看查看详细。
销毁
@DatabaseTearDown注解可以用来重置数据库表当测试完成时。和@DatabaseSetup一样的是,这个注解可以在方法或者类层面上起效。当使用@DatabaseTearDown时,使用和@DatabaseSetup相同的方式使用值和类别属性。
期望的结果
@ExpectedDatabase注解可以用来在测试完成时,检验数据库内容。当一个测试执行了一个插入,更新或者删除操作,你将典型的使用这个注解。你可以将这个注解用到一个单一的测试方法或者类中。当用在类级别上时,每个方法执行后都会调用检验程序。
@ExpectedDatabase 注解需要一个value属性,这个属性引用数据集文件用来检验结果。下面是一个典型的例子。
@ExpectedDatabase("expectedData.xml")@ExpectedDatabase注解支持两种不同的模式。DatabaseAssertionMode.DEFAULT作为一个标准的DbUnit测试运行,执行一个完整的期望数据集和实际数据集的比对。DatabaseAssertionMode.NON_STRICT将忽略没有在期望数据集中出现,但是在实际数据集中出现的 表和列名。当集成测试执行在实际数据库包含很多有很多列的表中, 这将十分有用。我们不需要定义所有的这些,只需要我们感兴趣的表和列。
注意:如果你在测试中使用这个注解的同时还使用了@Transactional,你需要一个可选的配置。参见下面的小节。
事务
如果你配置DBUnit测试,使用了DbUnitTestExecutionListener以及使用了TransactionalTestExcecutionListener,你可能会经历事务在你的数据设置之前没有启动的问题,或者在期望的数据集校验之前就回滚的问题。为了让DBUnit支持@Transactional 测试,你需要使用TransactionDbUnitTestExecutionListener类。
注意:TransactionDbUnitExecutionListener提供了DBUnit和Transactional支持。当使用TransactionDbUnitTestExecutionListener时,你必须禁止使用TransactionalTestExecutionListener或者DbUnitTestExceutionListener类。
下面是一个典型的JUnit4测试类的注解:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @Transactional @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalDbUnitTestExecutionListener.class })事务在@DatabaseSetup之前被调用,在@DatabaseTearDown 和@ExpectedDatabase之后被结束。
DbUnitTestExecutionListener的高级配置
注意:这个小结仅仅在你使用DbUnitTestExecutionListener时起效。如果你使用了Junit@Rule,参看下一小结。
如果你需要为DBUnit配置高级选项,@DbUnitConfiguration注解可以被使用。
databaseConnection属性允许你精确定位一个包含数据连接的Spring Context中的bean。当没有定义名字时也可以使用。这个bean必须实现IDatabaseConnection或者一个DataSource.
DbUnitRule的高级配置
注意:本小节仅仅在你使用DBUnitRule JUnit @Rule时起效。查看下面的部分如果你使用的时DbUnitTestExecutionListener;
DBUnitRule JUnit rule 将查看你的测试类中的私有的字段,用来配置自己。如果你的测试包括了一个DataSource字段或者一个IDataBaseConnection字段,这个将被使用来获取一个数据库连接。你也可以包括一个DataSetLoader字段如果你希望能够使用一个自定义加载器当读取数据集的时候(看下面)。
如果你需要更多的细粒度的控制,你也可以调用rule上的setter方法。
自定义IDatabaseConnections
在一些场合下你可能需要创建一个IDatabaseConnection利用一个特定的DBUnit配置。不巧的是,标准DBUnit DatabaseConfig类不能被Sprign容易的使用。为了克服这个缺陷,DatabaseConfigBean提供了一个可选的方法用来配置一个连接。提供标准的getter/setter提供给所有的配置选项。DatabaseDataSourceConnectionFactoryBean 接收一个配置属性,应该用来构建最终的连接。下面是一个典型的例子:
<bean id="dbUnitDatabaseConfig" class="com.github.springtestdbunit.bean.DatabaseConfigBean"> <property name="skipOracleRecyclebinTables" value="true"/> </bean> <bean id="dbUnitDatabaseConnection" class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean"> <property name="databaseConfig" ref="dbUnitDatabaseConfig"/> </bean>注意:在最多的场合下,username和password属性必须不被DataabaseDataSourceConnectionFactoryBean设置.这些属性引起DBUnit启动一个新的事物,将导致一个不能预料的行为。
写一个数据集加载器
默认情况下,DBUnit数据集通过普通的XML文件加载。如果你需要从其他数据源中加载数据,你想要写你自己的数据集加载器,配置你的测试来使用它。自定义加载器必须实现DataSetLoader接口,提供一个loadDataSet方法的实现。AbstractDataSetLoader对于大多数加载器而言,提供了一个方便的基类,也可以使用。
下面是一个从CSV文件中读取数据的加载器的例子。
public class CsvDataSetLoader extends AbstractDataSetLoader { protected IDataSet createDataSet(Resource resource) throws Exception { return new CsvURLDataSet(resource.getURL()); } }参考上面的详细信息用来配置一个测试类使用加载器。