我有罪,直到現在才寫集成測試(至少針對數據庫相關事務)。 因此,為了消除內感,我閱讀了如何在周末以最少的努力實現這一目標。 提供了一個小示例,描述了如何使用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