使用Unitils测试DAO

上个月在博客中,讲了怎么使用dbunit帮助测试dao。但是在使用过程中,发现,使用dbunit的过程依然很繁琐。因此考虑对dbunit的使用做一些封装。期间发现开源工具Unitils已经很好的完成了这个工作。Unitils,由多个模块构成。 DatabaseModule,DbUnitModule,HibernateModule ,MockModule,EasyMockModule,InjectModule,SpringModule

我感兴趣的是dbunit和spring整合的两个模块。结合这两个模块可以很方便的完成dao的测试。

 

在Spring中结合Dbunit对Dao进行集成单元测试

 

Unitils Tutorial

 

Using Unitils Step by Step

首先包含,unitils的库和依赖库

<dependency>
	<groupId>org.unitils</groupId>
	<artifactId>unitils</artifactId>
	<version>2.4</version>
	<scope>test</scope>
</dependency>
 

在classpath下配置 unitils.properties配置文件

database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/subcenter
database.userName=subcenter
database.password=subcenter
database.schemaNames=subcenter
database.dialect=mysql

 

在测试类上声明@RunWith(UnitilsJUnit4TestClassRunner.class),或者集成Untils提供的基类org.unitils.UnitilsJUnit3,org.unitils.UnitilsJUnit4,org.unitils.UnitilsTestNG

 

配置使用spring

在测试类中声明spring的配置文件

@SpringApplicationContext( { "classpath:persistence-test.xml",
		"classpath:beans.xml" })

 

在测试类中注入Spring bean

@SpringBeanByType
UserDAO target;

//或者注入Applicationcontext
@SpringApplicationContext
ApplicationContext  applicationcontext;

 

前面在unitisl配置文件中,制定了数据库连接,为了让spring中的bean使用相同的数据连接,可以在spring中使用unitils提供的数据源

<bean id="datasource" class="org.unitils.database.UnitilsDataSourceFactoryBean" />

 

这样unitils提供的测试数据插入和验证操作,能够和dao运行在同一个事务下。

 

同样的unitils也可以制定测试方法在执行后回滚数据库,撤销的数据库的更改。在测试类或方法上声明

@Transactional(TransactionMode.ROLLBACK)

 最后测试类应该为:

@RunWith(UnitilsJUnit4TestClassRunner.class)
@SpringApplicationContext( { "classpath:persistence-test.xml",
		"classpath:beans.xml" })
@Transactional(TransactionMode.ROLLBACK)
public class PromotionInfoDAOTest {
	@SpringBeanByType
	PromotionInfoDAO target;
}

 

使用unitils插入测试数据:

 

在测试方法上使用@DataSet注解,让unitils把以dbunit的FlatXmlDataSet格式制定的数据插入到数据库,默认使用的插入操作是CLEAN_INSERT,即插入前先清空涉及到的表。

 

在测试方法上使用@ExpectedDataSet注解,让unitils验证操作后的数据库。

 

	@Test
	@DataSet("PromotionInfoDAOTest-emputy.xml")
	@ExpectedDataSet("PromotionInfoDAOTest-after.xml")
	public void add() throws Exception {

		PromotionInfoDO promotion = DBUnitUtils.createBean(afterDataset,
				"promotion", PromotionInfoDO.class);
		promotion.setCategory(new PromotionCategoryDO(2));
		target.insert(promotion);
	}

 Notice

使用@DataSet时,可以指定一个空的XML文件,让unitils清空数据库。例如

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<promotion />
</dataset>  

 

使用@ExpectedDataSet验证时,unitils只会比较出现在xml文件中的字段和表。那么自增ID等不方便比较的字段可以不用在xml文件中配置,不进行比较。

 

More

是测试时,比如测试一个插入操作,我们首先写一个XML配置文件,写上要插入的表数据,然后创建一个相同字段的Bean,插入到数据库中,最后验证相同。

这个工程中,重复配置了两篇数据,不符合DYR原则。因此,我写了一个小工具类,可以从dbunits的FlatXmlDataset文件中创建Bean。

PromotionInfoDO promotion = DBUnitUtils.createBean(afterDataset,
				"promotion", PromotionInfoDO.class);
 
/**
 * 
 * 从dbunit的FlatXmlDataSet格式的xml文件创建bean
 * 
 * @author mshijie
 * 
 */
public class DBUnitUtils {

	/**
	 * 从dbunit的flatXmlDataSet中,创建多个bean
	 * 
	 * @param <T>
	 * @param file
	 * @param clazz
	 * @param ignoredProps
	 * @return
	 * @throws Exception
	 */
	public static <T> List<T> createBeans(String file, String tableName,
			Class<T> clazz) throws Exception {
                  //................................
	}

	/**
	 * 从dbunit的flatXmlDataSet中,创建bean
	 * 
	 * @param <T>
	 * @param file
	 * @param clazz
	 * @param ignoredProps
	 * @return
	 * @throws Exception
	 */
	public static <T> T createBean(String file, String tableName, Class<T> clazz)
			throws Exception {
		 //................................	
         }

        //...............................................................
}
 

完整代码见附件

 

 

你可能感兴趣的:(DAO,spring,bean,mysql,单元测试)