我有罪,直到现在才写集成测试(至少针对数据库相关事务)。 因此,为了消除内感,我阅读了如何在周末以最少的努力实现这一目标。 提供了一个小示例,描述了如何使用Spring和Hibernate轻松实现这一目标。 通过集成测试,您可以测试DAO(数据访问对象)层,而无需部署应用程序。 对我来说,这是一个巨大的优势,因为现在我甚至可以在不运行应用程序的情况下测试我的条件,命名查询和排序。
休眠中有一个属性,可让您指定初始化会话工厂时要运行的sql脚本。 这样,我现在可以用DAO层所需的数据填充表。 属性如下:
<prop key='hibernate.hbm2ddl.import_files'>import.sql</prop>
根据hibernate 文档 ,您可以有许多以逗号分隔的sql脚本。这里的一个陷阱是您无法使用该脚本创建表。 因为需要首先创建架构才能运行脚本。 即使您在脚本中发出了create table语句,执行脚本时也会忽略该语句,正如我所看到的那样。
让我首先向您展示我要测试的DAO课;
package com.unittest.session.example1.dao;import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import com.unittest.session.example1.domain.Employee;@Transactional(propagation = Propagation.REQUIRED)
public interface EmployeeDAO {public Long createEmployee(Employee emp);public Employee getEmployeeById(Long id);
}
package com.unittest.session.example1.dao.hibernate;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import com.unittest.session.example1.dao.EmployeeDAO;
import com.unittest.session.example1.domain.Employee;public class EmployeeHibernateDAOImpl extends HibernateDaoSupport implementsEmployeeDAO {@Overridepublic Long createEmployee(Employee emp) {getHibernateTemplate().persist(emp);return emp.getEmpId();}public Employee getEmployeeById(Long id) {return getHibernateTemplate().get(Employee.class, id);}
}
没什么大不了的,只是一个简单的DAO,它有两种方法,一种是持久化,另一种是检索。 对我来说,测试检索方法需要用一些数据填充Employee表。 这是前面介绍的导入sql脚本起作用的地方。 import.sql文件如下所示;
insert into Employee (empId,emp_name) values (1,'Emp test');
这只是一个基本脚本,我在其中将一条记录插入到employee表中。 在此再次注意,employee表应该通过hibernate auto create DDL选项创建,以便运行sql脚本。 更多信息可以在这里找到。 同样,我实例中的import.sql脚本也位于类路径中。 这是为了在创建Session工厂时能够将其拾取而执行的。
接下来,让我们看看使用Spring运行集成测试有多么容易。
package com.unittest.session.example1.dao.hibernate;import static org.junit.Assert.*;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;import com.unittest.session.example1.dao.EmployeeDAO;
import com.unittest.session.example1.domain.Employee;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations='classpath:spring-context.xml')
@TransactionConfiguration(defaultRollback=true,transactionManager='transactionManager')
public class EmployeeHibernateDAOImplTest {@Autowiredprivate EmployeeDAO employeeDAO;@Testpublic void testGetEmployeeById() {Employee emp = employeeDAO.getEmployeeById(1L);assertNotNull(emp);}@Testpublic void testCreateEmployee(){Employee emp = new Employee();emp.setName('Emp123');Long key = employeeDAO.createEmployee(emp);assertEquals(2L, key.longValue());}}
这里要注意的几件事是,您需要指示在Spring上下文中运行测试。 为此 ,我们使用SpringJUnit4ClassRunner 。 还将transction属性设置为defaultRollback = true。 请注意,对于MySQL,要使其正常工作,您的表必须设置InnoDB引擎,因为MyISAM引擎不支持事务。
最后,我介绍了弹簧配置,它可以将所有东西连接起来;
<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:aop='http://www.springframework.org/schema/aop'xmlns:tx='http://www.springframework.org/schema/tx' xmlns:context='http://www.springframework.org/schema/context'xsi:schemaLocation=' http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd'><context:component-scan base-package='com.unittest.session.example1' /><context:annotation-config /><tx:annotation-driven /><bean id='sessionFactory'class='org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean'><property name='packagesToScan'><list><value>com.unittest.session.example1.**.*</value></list></property><property name='hibernateProperties'><props><prop key='hibernate.dialect'>org.hibernate.dialect.MySQLDialect</prop><prop key='hibernate.connection.driver_class'>com.mysql.jdbc.Driver</prop><prop key='hibernate.connection.url'>jdbc:mysql://localhost:3306/hbmex1</prop><prop key='hibernate.connection.username'>root</prop><prop key='hibernate.connection.password'>password</prop><prop key='hibernate.show_sql'>true</prop><prop key='hibernate.dialect'>org.hibernate.dialect.MySQLDialect</prop><!-- --><prop key='hibernate.hbm2ddl.auto'>create</prop><prop key='hibernate.hbm2ddl.import_files'>import.sql</prop></props></property></bean><bean id='empDAO'class='com.unittest.session.example1.dao.hibernate.EmployeeHibernateDAOImpl'><property name='sessionFactory' ref='sessionFactory' /></bean><bean id='transactionManager'class='org.springframework.orm.hibernate3.HibernateTransactionManager'><property name='sessionFactory' ref='sessionFactory' /></bean></beans>
就是这样。 我个人宁愿使用重量更轻的内存数据库(例如hsqldb )来运行集成测试。
这是供任何想运行该程序并尝试使用它的人的eclipse项目。
参考:来自My Journey Through IT博客的JCG合作伙伴 Dinuka Arseculeratne 与Spring + Hibernate进行集成测试有多酷 。
翻译自: https://www.javacodegeeks.com/2012/11/how-cool-is-integration-testing-with-spring-and-hibernate.html