使用 Spring 测试注释来进行常见的 Junit4 或者 TestNG 的单元测试,同时支持访问 Spring 的 beanFactory 和进行自动化的事务管理。
一、spring测试注解标签
1. @ContextConfiguration 和 @Configuration 的使用

Spring 3.0 新提供的特性 @Configuration,这个注释标签允许您用 Java 语言来定义 bean 实例。

  1. package config;
  2. import org.Springframework.beans.factory.annotation.Autowired;
  3. import org.Springframework.context.annotation.Bean;
  4. import org.Springframework.context.annotation.Configuration;
  5. import org.Springframework.jdbc.datasource.DriverManagerDataSource;
  6. import service.AccountService;
  7. import service.Initializer;
  8. import DAO.AccountDao;
  9. @Configuration
  10. public class SpringDb2Config {
  11. private @Autowired DriverManagerDataSource datasource;
  12. @Bean
  13. public Initializer initer() {
  14. return new Initializer();
  15. }
  16. @Bean
  17. public AccountDao accountDao() {
  18. AccountDao DAO = new AccountDao();
  19. DAO.setDataSource(datasource);
  20. return DAO;
  21. }
  22. @Bean
  23. public AccountService accountService() {
  24. return new AccountService();
  25. }
  26. }

通过@ContextConfiguration指定配置文件,Spring test framework 会自动加载 XML 文件,也是我们采用的方式。

2.@DirtiesContext
缺省情况下,Spring 测试框架一旦加载 applicationContext 后,将一直缓存,不会改变,但是,
由于 Spring 允许在运行期修改 applicationContext 的定义,例如在运行期获取 applicationContext,然后调用 registerSingleton 方法来动态的注册新的 bean,这样的情况下,如果我们还使用 Spring 测试框架的被修改过 applicationContext,则会带来测试问题,我们必须能够在运行期重新加载 applicationContext,这个时候,我们可以在测试类或者方法上注释:@DirtiesContext,作用如下:
如果定义在类上(缺省),则在此测试类运行完成后,重新加载 applicationContext
如果定义在方法上,即表示测试方法运行完成后,重新加载 applicationContext

3.@Transactional、@TransactionConfiguration 和 @Rollback
缺省情况下,Spring 测试框架将事务管理委托到名为 transactionManager 的 bean 上,如果您的事务管理器不是这个名字,那需要指定 transactionManager 属性名称,还可以指定 defaultRollback 属性,缺省为 true,即所有的方法都 rollback,您可以指定为 false,这样,在一些需要 rollback 的方法,指定注释标签 @Rollback(true)即可。事务的注解可以具体到方法

4.@Repeat
通过 @Repeat,您可以轻松的多次执行测试用例,而不用自己写 for 循环,使用方法:
 @Repeat(3) 
 @Test(expected=IllegalArgumentException.class) 
 public void testInsertException() { 
service.insertIfNotExist(null); 
 }
这样,testInsertException 就能被执行 3 次。

5.@ActiveProfiles 
从 Spring 3.2 以后,Spring 开始支持使用 @ActiveProfiles 来指定测试类加载的配置包,比如您的配置文件只有一个,但是需要兼容生产环境的配置和单元测试的配置,那么您可以使用 profile 的方式来定义 beans,如下:

  1. <beans xmlns="http://www.Springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.Springframework.org/schema/beans
  4. http://www.Springframework.org/schema/beans/Spring-beans-3.2.xsd">
  5. <beans profile="test">
  6. <bean id="datasource"
  7. class="org.Springframework.jdbc.datasource.DriverManagerDataSource">
  8. <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
  9. <property name="url" value="jdbc:hsqldb:hsql://localhost" />
  10. <property name="username" value="sa"/>
  11. <property name="password" value=""/>
  12. </bean>
  13. </beans>
  14. <beans profile="production">
  15. <bean id="datasource"
  16. class="org.Springframework.jdbc.datasource.DriverManagerDataSource">
  17. <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
  18. <property name="url" value="jdbc:hsqldb:hsql://localhost/prod" />
  19. <property name="username" value="sa"/>
  20. <property name="password" value=""/>
  21. </bean>
  22. </beans>
  23. <beans profile="test,production">
  24. <bean id="transactionManager"
  25. class="org.Springframework.jdbc.datasource.DataSourceTransactionManager">
  26. <property name="dataSource" ref="datasource"></property>
  27. </bean>
  28. <bean id="initer" init-method="init" class="service.Initializer">
  29. </bean>
  30. <bean id="accountDao" depends-on="initer" class="DAO.AccountDao">
  31. <property name="dataSource" ref="datasource"/>
  32. </bean>
  33. <bean id="accountService" class="service.AccountService">
  34. </bean>
  35. <bean id="envSetter" class="EnvSetter"/>
  36. </beans>
  37. </beans>

上面的定义,我们看到:
在 XML 头中我们引用了 Spring 3.2 的 beans 定义,因为只有 Spring 3.2+ 才支持基于 profile 的定义
在 <beans> 根节点下可以嵌套 <beans> 定义,要指定 profile 属性,这个配置中,我们定义了两个 datasource,一个属于 test profile,一个输入 production profile,这样,我们就能在测试程序中加载 test profile,不影响 production 数据库了
在下面定义了一些属于两个 profile 的 beans,即 <beans profile=”test,production”> 这样方便重用一些 bean 的定义,因为这些 bean 在两个 profile 中都是一样的

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration("/config/Spring-db.xml")
  3. @Transactional
  4. @ActiveProfiles("test")
  5. public class AccountServiceTest {
  6. ...
  7. }

注意上面的 @ActiveProfiles,可以指定一个或者多个 profile,这样我们的测试类就仅仅加载这些名字的 profile 中定义的 bean 实例。

下面看一个配置实例:

添加依赖:

  1. <dependency>
  2. <groupId>junit</groupId>
  3. <artifactId>junit</artifactId>
  4. <version>4.10</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework</groupId>
  8. <artifactId>spring-test</artifactId>
  9. <version>4.0.1.RELEASE</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework</groupId>
  13. <artifactId>spring-context</artifactId>
  14. <version>4.0.1.RELEASE</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.springframework</groupId>
  18. <artifactId>spring-tx</artifactId>
  19. <version>4.0.1.RELEASE</version>
  20. </dependency>

spring配置:applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context-3.0.xsd"
  9. default-lazy-init="false">
  10. <description>Spring公共配置 </description>
  11. <context:component-scan base-package="cn.slimsmart.unit.test.demo" />
  12. </beans>

AddServiceImpl添加@service注解

测试类:

    1. package cn.slimsmart.unit.test.demo.junit;
    2. import static org.junit.Assert.assertTrue;
    3. import org.junit.After;
    4. import org.junit.Before;
    5. import org.junit.Test;
    6. import org.junit.runner.RunWith;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.test.context.ActiveProfiles;
    9. import org.springframework.test.context.ContextConfiguration;
    10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    11. import org.springframework.test.context.transaction.TransactionConfiguration;
    12. import org.springframework.transaction.annotation.Transactional;
    13. //用来说明此测试类的运行者,这里用了 SpringJUnit4ClassRunner
    14. @RunWith(SpringJUnit4ClassRunner.class)
    15. //指定 Spring 配置信息的来源,支持指定 XML 文件位置或者 Spring 配置类名
    16. @ContextConfiguration(locations = { "classpath*:/applicationContext.xml" })
    17. //表明此测试类的事务启用,这样所有的测试方案都会自动的 rollback,
    18. //@Transactional
    19. //defaultRollback,是否回滚,默认为true
    20. //transactionManager:指定事务管理器一般在spring配置文件里面配置
    21. //@TransactionConfiguration(defaultRollback=true,transactionManager="transactionManager")
    22. //但是需要兼容生产环境的配置和单元测试的配置,那么您可以使用 profile 的方式来定义 beans,
    23. //@ActiveProfiles("test")
    24. public class JunitSpringTest {
    25. @Autowired
    26. private AddService addService;
    27. @Before
    28. public void setUp(){
    29. System.out.println("初始化");
    30. }
    31. @Test
    32. public void testAdd() {
    33. assertTrue(addService.add(1, 1) == 2);
    34. }
    35. @After
    36. public void destroy() {
    37. System.out.println("退出,资源释放");
    38. }
    39. }

Junit 之 与Spring集成的更多相关文章

  1. Spring系列之新注解配置+Spring集成junit+注解注入

    Spring系列之注解配置 Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率 你本来要写一段很长的代码来构造一个 ...

  2. 使用CXF与Spring集成实现RESTFul WebService

    以下引用与网络中!!!     一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...

  3. elasticsearch spring 集成

    elasticsearch spring 集成 项目清单   elasticsearch服务下载包括其中插件和分词   http://download.csdn.net/detail/u0142011 ...

  4. RabbitMQ安装和使用(和Spring集成)

    一.安装Rabbit MQ Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装Rabbit MQ的前提是安装Erlang.通过下面两个连接下载安装3.2.3 版本: 下载并安装 E ...

  5. SSM框架开发web项目系列(五) Spring集成MyBatis

    前言 在前面的MyBatis部分内容中,我们已经可以独立的基于MyBatis构建一个数据库访问层应用,但是在实际的项目开发中,我们的程序不会这么简单,层次也更加复杂,除了这里说到的持久层,还有业务逻辑 ...

  6. 消息中间件系列四:RabbitMQ与Spring集成

    一.RabbitMQ与Spring集成  准备工作: 分别新建名为RabbitMQSpringProducer和RabbitMQSpringConsumer的maven web工程 在pom.xml文 ...

  7. Spring集成MyBatis的使用-使用SqlSessionTemplate

    Spring集成MyBatis的使用 Spring集成MyBatis,早期是使用SqlSessionTemplate,当时并没有用Mapper映射器,既然是早期,当然跟使用Mapper映射器是存在一些 ...

  8. Spring集成MyBatis的使用-使用Mapper映射器

    Spring集成MyBatis使用 前面复习MyBatis时,发现在测试时,需要手动创建sqlSessionFactory,Spring将帮忙自动创建sqlSessionFactory,并且将自动扫描 ...

  9. Spring集成Mybatis,spring4.x整合Mybatis3.x

    Spring集成Mybatis,spring4.x整合Mybatis3.x ============================== 蕃薯耀 2018年3月14日 http://www.cnblo ...

随机推荐

  1. struts2的java.lang.NoSuchMethodException错误

    不久前在学习struts时出现这个错误,在网上搜索了半天,发现答案不一.将其总结如下,以方便大家参考. 1. 你有没有试试看 其它的方法能不能用,要是都是这种情况的话,可能是你的Action类没有继承 ...

  2. How to change Eclipse loading image

    Eclipse IDE has many customize components, the splash welcome image (purple color loading image) is ...

  3. List GroupBy真实用法,Reflection(反射)用法,Enum用法,正则,搜索下拉布局

    1.List  GroupBy 用法 var _roomProducts = homesingProducts.GroupBy(t => t.RoomName); RoomedProducts ...

  4. __x__(30)0908第五天__导航条的练习 <div>版本

    效果图:  html源代码: <!doctype html> <html> <head> <meta charset="utf-8" /& ...

  5. HDFS的WEB页面访问常见问题

    HDFS的WEB UI管理页面 50070 端口 无法访问解决办法! 本文基于HADOOP-3..1.0,Cecntos7.0环境下进行测试,所以遇到很多新鲜的问题: 特别注意:HaDoop3.0之前 ...

  6. 利用XPT2046制作一个电位器AD转换装置

    XPT2046是一款四线制电阻触摸屏控制芯片,内含12位分辨率125KHz转换速率逐步逼近型A/D转换器,支持从1.5V到5.25V的低电压I/O接口. 所谓逐步逼近型,就是输入一个模拟量,其与100 ...

  7. Ubuntu软件安装与卸载

    ubuntu软件安装与卸载 更新Ubuntu软件下载地址 1. 寻找国内镜像源 所谓的镜像源:可以理解为提供下载软件的地方,比如Android手机上可以下载软件的91手机助手:iOS手机上可以下载软件 ...

  8. Sql中获取表结构(字段名称,类型,长度,说明)

    Sql中获取表结构(字段名称,类型,长度,说明) SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Descript ...

  9. js表单提交到后台对象接收

    $.extend({ StandardPost:function(url,args){ var form = $("<form method='post' target='_blank ...

  10. 小甲鱼零基础python课后题 P21 020函数:内嵌函数和闭包函数

    测试题 0.如果希望在函数中修改全局变量的值,应该使用什么关键字? 答:globe 1.在嵌套函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字? 答:nonlocal 2.pyth ...