Spring在接口测试中的应用
1引言
本文旨在介绍Spring的JdbcTemplate和TestContext,希望通过简单的示例可以使初学者能够快速上手,在项目测试中灵活运用。
2SimpleJdbcTemplate
在很多测试中需要访问数据库验证业务逻辑,你正在使用什么工具?Spring的SimpleJdbcTemplate是个不错的选择。该工具封装了常用的Jdbc操作,其中一个很方便的特性是其会迭代查询的ResultSet结果集为方便操作的java对象。下面通过简单的示例说明其用法。
2.1简单应用示例
<bean id="propertyConfigurer" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="itemDataSource" value="${jdbc.driverClassName}"/>
<property name="url" value="${dev-db1.jdbc.url}"/>
<property name="username" value="${taobao.jdbc.username}"/>
<property name="password" value="${taobao.jdbc.password}"/>
</bean>
</beans>
3.2简单应用示例@ContextConfiguration(locations = { "classpath:applicationContext.xml" })//①
public class BaseCase extends AbstractJUnit4SpringContextTests {//②
}
@ContextConfiguration(locations = { "classpath:datasource-item.xml" })//③
public class ItemAddTest extends BaseCase {
private SimpleJdbcTemplate jdbcTemplate;
@Autowired//④
public void init(DataSource dataSource) {
jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
}
上面的示例对TestContext的应用非常简单,归纳起来就是一个基类两个注解。
一个基类:AbstractJUnit4SpringContextTests,如②,如果你测试的业务支持事务,可继承AbstractTransactionalJUnit4SpringContextTests,同时在配置文件里加上事务控制相关内容。注解一:用@ContextConfiguration引入Spring配置文件。如果容器中配置了类型相同的多个Bean,可用@Qualifier指定名称,例如如果类中引入了多个数据源,其示例代码如下@Autowired另外@Autowired还可标注于成员变量和构造器,例如如果配置了要测试的类TaobaoDirectJsonRestClient,可通过下面的方法实例化。
public void init(@Qualifier("itemDataSource")
DataSource dataSource) {
jdbcTemplateItem = new SimpleJdbcTemplate(dataSource);
}
@Autowired
public void init2(@Qualifier("userDataSource")
DataSource dataSource) {
jdbcTemplateUser = new SimpleJdbcTemplate(dataSource);
}@Autowired
private TaobaoDirectJsonRestClient client;
3.3源码分析
在上面的示例中我们通过继承AbstractJUnit4SpringContextTests和@ContextConfiguration标注就完成了Spring容器的启动和与Junit的结合,下面我们通过源码分析更进一步了解其深层原理。
AbstractJUnit4SpringContextTests的骨干代码如下:@RunWith(SpringJUnit4ClassRunner.class)//①
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})//②
public abstract class AbstractJUnit4SpringContextTests implements ApplicationContextAware {
在②处的标注跟Junit没啥关系,我们先看①处的@RunWith, Junit4中广泛使用测试运行器,通过@RunWith注解告诉Junit采用何种运行器,事实上如果没有指定@RunWith,那么测试类仍然会使用一个默认运行器 (org.junit.internal.runners.TestClassRunner,继承于JUnit4ClassRunner)执行,我们继续看SpringJUnit4ClassRunner做了什么。SpringJUnit4ClassRunner核心代码如下:public class SpringJUnit4ClassRunner extends JUnit4ClassRunner {
private final TestContextManager testContextManager;
@Override
protected Object createTest() throws Exception {
Object testInstance = super.createTest();
getTestContextManager().prepareTestInstance(testInstance);// ③
return testInstance;
}
//这里忽略了其他非关键代码
}
SpringJUnit4ClassRunner同样继承了JUnit4ClassRunner,主要覆盖了其createTest方法,在createTest方法里利用TestContextManager对testInstance进行处理。继续再看看TestContextManager的关键代码。public class TestContextManager {
private final TestContext testContext;// ④
private final List testExecutionListeners = new ArrayList(); //⑤,与前面的②呼应
至此脉络大致清晰,对Spring TestContext核心类总结如下:
SpringJunit4ClassRunner:Junit4运行器(见①),是Spring TestContext与Junit4结合的根本。TestContext:封装了运行测试用例的上下文。TestContextManager:Spring TestContext的主入口点, 管理TestContext(见④)和TestExecutionListener(见⑤)TestExecutionListener:负责响应TestContextManager发布的事件,执行具体的操作,其中常用的Listener见②。3.4思考&实践
Spring TestContext本身运用是比较简单的,只需要准备配置文件、继承它提供的抽象类以及掌握几个注解即可。另外,通过源码分析我们发现了两个可扩展点,如果有必要可以利用这些扩展点在不改变其程序的情况下,开发符合我们自己需求的工具类。
在我的下篇博文-Managing test data with DbUnit And @XDataSet里展示了运用扩展点二定制一个监听器,该监听器负责根据测试类或方法中的注解完成测试数据的准备和清理,具有支持多数据源及多种类型的数据集如XLS、XML等特性。
4小结
本文通过简单的示例说明了如何在接口测试中应用Spring的JdbcTemplate和TestContext,最后通过源码分析发现了两个可扩展点,为量身定做符合自己的测试工具找到了入口点。关于对其中一个扩展点TestExecutionListener的实践应用请关注我的下篇博文-Managing test data with DbUnit And @XDataSet。