`
chxiaowu
  • 浏览: 235136 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Spring在接口测试中的应用

阅读更多

1 引言
本文旨在介绍Spring的JdbcTemplate和TestContext,希望通过简单的示例可以使初学者能够快速上手,在项目测试中灵活运用。
2 SimpleJdbcTemplate
在很多测试中需要访问数据库验证业务逻辑,你正在使用什么工具?Spring的SimpleJdbcTemplate是个不错的选择。该工具封装了常用的 Jdbc操作,其中一个很方便的特性是其会迭代查询的ResultSet结果集为方便操作的java对象。下面通过简单的示例说明其用法。
2.1 简单应用示例

  • 2.1.1 Construct new instance
    SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
  • 2.1.2 queryForInt
    The query is expected to be a single row/single column query that results in an int value.
    String sql = "SELECT COUNT(1) FROM bmw_users";
    int result = jdbcTemplate.queryForInt(sql);
  • 2.1.3 queryForList
    The results will be mapped to a List (one entry for each row) of Maps (one entry for each column, using the column name as the key).
    String sql = "SELECT * FROM bmw_users WHERE city=? AND user_gender=? ";
    List<Map> resutls = jdbcTemplate.queryForList(sql, "杭州","m");
  • 2.1.4 query
    like queryForList but mapping each row to a Java object
    String sql = "SELECT user_id userId,nick,user_gender sex FROM bmw_users WHERE city=? AND user_gender=?";
    List resutls = jdbcTemplate.query(sql, ParameterizedBeanPropertyRowMapper.newInstance(User.class),"杭州","m");
  • 2.1.5 update or delete data
    String sql = "DELETE FROM bmw_users WHERE id=? ";
    jdbcTemplate.update(sql, “1111”);
  • 对SimpleJdbcTemplate的介绍就到这里,更多的用法可参考其JavaDoc或源码。

    2.2 思考&实践
    由于测试过程中用到的sql不会很复杂,我们利用SimpleJdbcTemplate可以封装一些常用的操作,在用例代码中甚至不需要编写sql语句即可完成数据库操作。下面的例子展示了运用封装的JdbcTestUtil根据条件查询某表的数据。
    Map args = new HashMap();
    args.put("nick", "tbtest561");
    List results = JdbcTestUtil.queryData(jdbcTemplate, "bmw_users", args);

    JdbcTestUtil的更多用法可参考svn…
    3 TestContext
    TestContext本来是为了测试基于Spring的应用程序而开发的,其实在非Spring程序测试中一样可以运用它,方便的解决配置等问题,而且 其提供的监听器机制为我们自定义工具对用例运行进行细微控制提供了良好的思路。下面通过简单的示例入手,接着通过分析源码,找出了可为我们所用的扩展点。
    3.1 合理准备配置文件

  • 3.1.1 基本配置文件(src/test/resources/applicationContext.xml)
    这个在基类文件中引入,子类配置会自动继承。这是个最大化的文件,基本包含了所有声明。

    <?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
    default-lazy-init="true">

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
    <list>
    <value>classpath:jdbc.properties</value>
    </list>
    </property>
    </bean>
    <!-- 使用annotation 自动注册bean -->
    <context:component-scan base-package="com.taobao"/>
    <context:annotation-config />
    </beans>

  • 3.1.2 Jdbc配置文件(src/test/resources/jdbc.properties)
    Jdbc配置信息统一在一个文件里,方便维护。
    jdbc.driverClassName=oracle.jdbc.OracleDriver

    dev-db1.jdbc.url=jdbc:oracle:thin:@192.168.205.37:1521:dev-db1
    taobao.jdbc.username=taobao
    taobao.jdbc.password=taobao

    dev-dbc.jdbc.url=jdbc:oracle:thin:@192.168.205.37:1521:dev-dbc
    tbcat.jdbc.username=tbcat
    tbcat.jdbc.password=tbcat

  • 3.1.3 数据源配置文件示例(src/test/resources/datasource-item.xml)
    我们测试项目需要多个数据源,但一个测试类一般只需要一个,因此建议每个数据源一个配置文件,用例类只需引入自己相关的配置文件。
    <?xml version="1.0" 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" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" 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配置文件。
    TestContext根据这个配置文件启动Spring容器。我们可在基类引入基础配置文件如①,在子类只引入相关的配置文件如③
  • 注解二:通过@Autowired自动装配Bean,如④。
    当 Spring 容器启动时,将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。
  • 如果容器中配置了类型相同的多个Bean,可用@Qualifier指定名称,例如如果类中引入了多个数据源,其示例代码如下
    @Autowired
    public void init(@Qualifier("itemDataSource")
    DataSource dataSource) {
    jdbcTemplateItem = new SimpleJdbcTemplate(dataSource);
    }
    @Autowired
    public void init2(@Qualifier("userDataSource")
    DataSource dataSource) {
    jdbcTemplateUser = new SimpleJdbcTemplate(dataSource);
    }
    另外@Autowired还可标注于成员变量和构造器,例如如果配置了要测试的类TaobaoDirectJsonRestClient,可通过下面的方法实例化。
    @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本身运用是比较简单的,只需要准备配置文件、继承它提供的抽象类以及掌握几个注解即可。另外,通过源码分析我们发现了两个可扩展点,如果有必要可以利用这些扩展点在不改变其程序的情况下,开发符合我们自己需求的工具类。

  • 扩展点一:Junit4提供的测试运行器机制。可编写自己的测试运行器类,该类应继承JUnit4ClassRunner,覆盖其关键的方法。
  • 扩展点二:Spring TestContext提供的TestExecutionListener机制。可编写自己的测试执行监听器,该类应实现TestExecutionListener接口。
  • 在我的下篇博文-Managing test data with DbUnit And @XDataSet 里展示了运用扩展点二定制一个监听器,该监听器负责根据测试类或方法中的注解完成测试数据的准备和清理,具有支持多数据源及多种类型的数据集如XLS、XML等特性。
    4 小结
    本文通过简单的示例说明了如何在接口测试中应用Spring的JdbcTemplate和TestContext,最后通过源码分析发现了两个可扩展点, 为量身定做符合自己的测试工具找到了入口点。关于对其中一个扩展点TestExecutionListener的实践应用请关注我的下篇博文-Managing test data with DbUnit And @XDataSet

    VN:F [1.9.6_1107]
    Rating: 10.0/10 (2 votes cast)
    Spring在接口测试中的应用 , 10.0 out of 10 based on 2 ratings 转载务必注明出处Taobao QA Team
    分享到:
    评论

    相关推荐

      Spring+3.x企业应用开发实战光盘源码(全)

       第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。  第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们...

      Spring-Reference_zh_CN(Spring中文参考手册)

      6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

      Spring中文帮助文档

      6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

      Spring.3.x企业应用开发实战(完整版).part2

       《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

      spring4.1核心包

      11.spring-jms-4.1.1.RELEASE.jar 简单封装jms api接口 jms: Java消息服务(Java Message Service)应用程序接口 12. spring-messaging-4.1.1.RELEASE.jar 消息发送 13. spring-orm-4.1.1.RELEASE.jar 14. spring-...

      spring4.3.9相关jar包

      Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。 外部依赖Commons Logging, (Log4J)。 spring-beans.jar(必须):这 个jar 文件是所有应用都要...

      Spring攻略(第二版 中文高清版).part1

      6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 ...

      spring源码阅读所需jar spring-cglib-repack-3.2.8.jar 和spring-objenesis-repack-2.6.jar

      Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单...

      Spring3.x企业应用开发实战(完整版) part1

       《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

      Spring 2.0 开发参考手册

      6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...

      spring-boot示例项目

      在基于Spring Boot、Spring Cloud 分布微服务开发过程中,根据实际项目环境,需要选择、集成符合项目需求的各种组件和积累各种解决方案。基于这样的背景下,我开源了本示例项目,方便大家快速上手Spring Boot、...

      Spring攻略(第二版 中文高清版).part2

      6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 ...

      Spring API

      6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

      Spring的学习笔记

      四、 测试代码: 8 五、 注意接口的使用: 8 第五课:IOC(DI)配置及应用 9 一、 什么是IOC、DI 9 二、 编辑xml文件时,没有提示 9 三、 注入类型(Injecting dependencies) 9 (一) setter注入类型Setter Injection 9 ...

      spring chm文档

      6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...

      spring security 参考手册中文版

      12.2.2在Spring MVC测试中以用户身份运行测试 106 12.2.3使用RequestPostProcessor在Spring MVC测试中以用户身份运行 106 作为用户在Spring MVC测试中使用注释运行 108 12.2.4测试HTTP基本认证 109 12.3 ...

      陈开雄 Spring+3.x企业应用开发实战光盘源码.zip

       第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。  第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们...

      spring3.1中文参考文档

      1.2.5 测试....................................................................................................................................................9 1.3 使用方案...............................

      Spring Security-3.0.1中文官方文档(翻译版)

      5.4. 在web 应用中验证 5.4.1. ExceptionTranslationFilter 5.4.2. AuthenticationEntryPoint 5.4.3. 验证机制 5.4.4. 在请求之间保存SecurityContext 。 5.5. Spring Security 中的访问控制(验证) ...

      搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

      6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant介绍 7.1.1 Ant简介 7.1.2 为什么要使用Ant 7.2 建立Ant的开发环境 7.2.1 下载Ant 7.2.2 配置Ant 7.3 Ant的使用方法 7.3.1 Ant能完成的...

    Global site tag (gtag.js) - Google Analytics