Spring 2.5 TestContext 测试框架用于测试基于 Spring 的程序,TestContext 测试框架和低版本 Spring 测试框架没有任何关系,是一个全新的基于注解的测试框架,为 Spring 推荐使用该测试框架。
备测试数据
相比于在测试方法中直接访问预定的数据记录,在测试方法执行前通过程序准备一些测试数据,然后在此基础上运行测试方法是比较好的策略,因为后者不需要对数据库的状态做假设。在 TestContext 中,你可以通过使用 JUnit 4.4 的 @Before 注解达到这个目的,请看下面的代码:
清单5. 为测试方法准备数据
package com.baobaotao.service; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Date; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4. AbstractTransactionalJUnit4SpringContextTests; import com.baobaotao.dao.UserDao; import com.baobaotao.domain.User; @ContextConfiguration
public
class
TestUserService extends AbstractTransactionalJUnit4SpringContextTests { @Autowired
private
UserService userService; @Autowired
private
UserDao userDao;
private
int
userId; @Before
//
① 准备测试数据
public
void
prepareTestData() { final String sql
=
"
insert into t_user(user_name,password) values('tom','1234')
"
; simpleJdbcTemplate.update(sql); KeyHolder keyHolder
=
new
GeneratedKeyHolder(); simpleJdbcTemplate.getJdbcOperations().update(
new
PreparedStatementCreator() {
public
PreparedStatement createPreparedStatement(Connection conn) throws SQLException { PreparedStatement ps
=
conn.prepareStatement(sql);
return
ps; } }, keyHolder); userId
=
keyHolder.getKey().intValue();
//
①-1 记录测试数据的id
} @Test
public
void
handleUserLogin(){ User user
=
userDao.getUserById(userId);
//
② 获取测试数据
user.setLastIp(
"
127.0.0.1
"
); Date now
=
new
Date(); user.setLastVisit(now.getTime()); userService.handleUserLogin(user); } }
标注 @Before 或 @After 注解的方法和测试方法运行在同一个事务中,但有时我们希望在测试方法的事务开始之前或完成之后执行某些方法以便获取数据库现场的一些情况。这时,可以使用 Spring TestContext 的 @BeforeTransaction 和 @AfterTransaction 注解来达到目录(这两个注解位于 org.springframework.test.context.transaction 包中)。
虽然大多数业务方法都会访问数据库,但也并非所有需要测试的业务方法都需要和数据库打交道。而在默认情况下,继承于 AbstractTransactionalJUnit4SpringContextTests 测试用例的所有测试方法都将工作于事务环境下,你可以显式地通过 @NotTransactional 注解,让测试方法不工作于事务环境下。
prepareTestData() 方法中使用到了 simpleJdbcTemplate 对象访问操作数据库,该对象在 AbstractTransactionalJUnit4SpringContextTests 抽象类中定义,只要 Spring 容器有配置数据源,simpleJdbcTemplate 就会被自动创建。同时该抽象类中还拥有一个 Spring 容器引用:applicationContext,你可以借助该成员变量访问 Spring 容器,执行获取 Bean,发布事件等操作。
此外,AbstractTransactionalJUnit4SpringContextTests 还提供了若干个访问数据库的便捷方法,说明如下:
protected int countRowsInTable(String tableName) :计算数据表的记录数。
protected int deleteFromTables(String... names):删除表中的记录,可以指定多张表。
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError):执行 SQL 脚本文件,在脚本文件中,其格式必须一个 SQL 语句一行。
在测试方法 handleUserLogin() 的 ② 处,我们通过 userDao 获取 prepareTestData() 添加的测试数据,测试方法在测试数据的基础上执行业务逻辑。使用这种测试方式后,在任何情况下运行 TestUserService 都不会发生业务逻辑之外的问题。
1
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13691617/viewspace-223910/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/13691617/viewspace-223910/