在进行dao的集成测试时候,数据清理,察看数据都是比较麻烦的事情,使用Spring-mock.jar可以帮助我们简化着一个过程。我举一个简单的例子,说明一下如何使用spring-mock。
首先是po, hbm.xml, dao, daoimpl没什么好说的:
Customer.java :
package rst.spring.mock;
import java.io.Serializable;
/** @author Hibernate CodeGenerator */ public class Customer implements Serializable {
/** identifier field */ private Long id;
/** nullable persistent field */ private String name;
/** full constructor */ public Customer(String name) { this.name = name; }
/** default constructor */ public Customer() { }
public Long getId() { return this.id; }
public void setId(Long id) { this.id = id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
}
Customer.hbm.xml :
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping package="rst.spring.mock"> <class name="Customer" table="customer"> <id name="id" column="id" type="long" unsaved-value="null"> <generator class="identity"/> </id> <property name="name" column="name" type="string"/> </class>
</hibernate-mapping>
CustomerDAO : /* * Created on 2005-3-25 */ package rst.spring.mock;
import org.springframework.dao.DataAccessException;
/** * @author rst * */ public interface CustomerDAO { public void add(Customer customer) throws DataAccessException; }
CustomerDAOImpl :
package rst.spring.mock;
import org.springframework.dao.DataAccessException; import org.springframework.orm.hibernate.support.HibernateDaoSupport;
/** * Class description. * * @author rst */ public class CustomerDAOHibernateImpl extends HibernateDaoSupport implements CustomerDAO{ public void add(Customer customer) throws DataAccessException{ this.getHibernateTemplate().save(customer); } }
|
然后测试的基类SpringDAOTestCase继承自AbstractTransactionalDataSourceSpringContextTests,目前只有一个指定测试用xml文件位置的逻辑。
package rst.spring.mock;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
/** * Class description. * * @author rst */ public abstract class SpringDAOTestCase extends AbstractTransactionalDataSourceSpringContextTests {
protected String[] getConfigLocations() { return new String[] { "test.xml" }; }
}
|
接着是我们真正测试的类CustomerDAOTest.java:
package rst.spring.mock;
/** * Class description. * * @author rst */ public class CustomerDaoTest extends SpringDAOTestCase {
private CustomerDAOHibernateImpl customerDAO;
protected void onSetUpInTransaction() throws Exception { super.onSetUpInTransaction(); //this.setPopulateProtectedVariables(true); customerDAO = (CustomerDAOHibernateImpl) this.applicationContext.getBean("customerDAO"); }
protected void onTearDownInTransaction() { customerDAO = null; }
public void testInsert() { Customer customer = new Customer(); customer.setName("javaeye"); customerDAO.add(customer); String name = (String) jdbcTemplate.queryForObject("select name from customer where id=?", new Object[]{customer.getId()}, String.class); assertEquals(customer.getName(), name); }
}
|
最后看看配置文件test.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- - Application context definition for Petclinic on Hibernate. --> <beans>
<!-- ========================= RESOURCE DEFINITIONS ========================= --> <!-- Configurer that replaces ${...} placeholders with values from a properties file --> <!-- (in this case, JDBC-related settings for the dataSource definition below) --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"><value>classpath:jdbc.properties</value></property> </bean>
<!-- Local DataSource that works in any environment --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>${jdbc.driverClassName}</value></property> <property name="url"><value>${jdbc.url}</value></property> <property name="username"><value>${jdbc.username}</value></property> <property name="password"><value>${jdbc.password}</value></property> </bean>
<!-- Hibernate SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> <property name="dataSource"><ref local="dataSource"/></property> <property name="mappingResources"> <value>rst/spring/mock/Customer.hbm.xml</value> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean>
<bean id="customerDAO" class="rst.spring.mock.CustomerDAOHibernateImpl"> <property name="hibernateTemplate"><ref local="hibernateTemplate"/></property> </bean> </beans>
|
这个文件很简单,不要忘记transactionManager的配置,Test类会自动装配的。
运行之后,就可以看到应有的结果,并且数据库中不会有数据污染。这个过程主要是开始一个transaction,然后开始你的test方法,执行dao操作,执行sql查询验证结果,最后无论成功失败rollback transaction。