2019独角兽企业重金招聘Python工程师标准>>>
若你所工作的项目使用到Spring、Hibernate、JPA,并且你想单元测试数据连接层(DAO),这篇文章可能帮到你。
当你打算测试DAO层,你需要连接数据库。但是你被不允许使用已有的数据库。原因可能有这两个,一是你有可能腐败将用来整合测试的数据,二是这数据其他开发组人员所专用的。
为了解决这问题,将用到内存数据库(in-memory database)。内存数据库是个不错选择。原因在于它测试完成后不留痕迹,且每次测试前都能保证数据库是空空的,没有任何表。
一个好的DAO测试应该保证数据库在测试前后状态一致。不留新添数据,回滚所有更新。
一、总要创建单元测试指定配置文件
这可以是创建DAO单元测试的第一步。这测试指定配置文件主要有用来测试的数据源信息,也就是用来连接内存数据库,覆盖主配置文件的数据源。譬如,主配置文件application-context.xml的数据源是MySQL,而测试指定配置文件application-context-test.xml的复用application-context.xml,除数据源需要另建为hsqldb内存数据库的外。
application-context-test.xml
class,hbm
create
true
org.hibernate.dialect.HSQLDialect
application-context.xml
class,hbm
update
true
org.hibernate.dialect.MySQL5Dialect
二、编写DAO层单元测试
下例将用到Spring-test和Junit测试框架。
@ContextConfiguration(locations = "classpath:application-context-test.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class TestEmployeeDAO {
@Autowired
private EmployeeDAO employeeDAO;
@Autowired
private DepartmentDAO departmentDAO;
@Rollback(true)
@Transactional
@Test
public void testAddDepartment() {
DepartmentEntity department = new DepartmentEntity("Information Technology");
departmentDAO.addDepartment(department);
List departments = departmentDAO.getAllDepartments();
Assert.assertEquals(department.getName(), departments.get(0).getName());
}
@Test
@Transactional
@Rollback(true)
public void testAddEmployee() {
DepartmentEntity department = new DepartmentEntity("Human Resource");
departmentDAO.addDepartment(department);
EmployeeEntity employee = new EmployeeEntity();
employee.setFirstName("Lokesh");
employee.setLastName("Gupta");
employee.setEmail("[email protected]");
employee.setDepartment(department);
employeeDAO.addEmployee(employee);
List departments = departmentDAO.getAllDepartments();
List employees = employeeDAO.getAllEmployees();
Assert.assertEquals(1, departments.size());
Assert.assertEquals(1, employees.size());
Assert.assertEquals(department.getName(), departments.get(0).getName());
Assert.assertEquals(employee.getEmail(), employees.get(0).getEmail());
}
}
需要注意几点
1.开始测试前,加载测试指定配置文件。
@ContextConfiguration(locations = "classpath:application-context-test.xml")
2.加载配置文件后,就能轻易注入依赖。
@Autowired
private EmployeeDAO employeeDAO;
@Autowired
private DepartmentDAO departmentDAO;
3.使用@Rollback(true)注解还原数据库状态。
@Test
@Transactional
@Rollback(true)
public void testAddDepartment()
{
//other code
}
4.每个测试都应创建一些数据,并验证这数据。重要的是,每一个测试用例都是独立的,它们不能有依赖关系。
三、项目结构
源码
引用
1.How you should unit test DAO layer