Junit 之 与Spring集成
使用 Spring 测试注释来进行常见的 Junit4 或者 TestNG 的单元测试,同时支持访问 Spring 的 beanFactory 和进行自动化的事务管理。
一、spring测试注解标签
1. @ContextConfiguration 和 @Configuration 的使用
Spring 3.0 新提供的特性 @Configuration,这个注释标签允许您用 Java 语言来定义 bean 实例。
- package config;
- import org.Springframework.beans.factory.annotation.Autowired;
- import org.Springframework.context.annotation.Bean;
- import org.Springframework.context.annotation.Configuration;
- import org.Springframework.jdbc.datasource.DriverManagerDataSource;
- import service.AccountService;
- import service.Initializer;
- import DAO.AccountDao;
- @Configuration
- public class SpringDb2Config {
- private @Autowired DriverManagerDataSource datasource;
- @Bean
- public Initializer initer() {
- return new Initializer();
- }
- @Bean
- public AccountDao accountDao() {
- AccountDao DAO = new AccountDao();
- DAO.setDataSource(datasource);
- return DAO;
- }
- @Bean
- public AccountService accountService() {
- return new AccountService();
- }
- }
通过@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,如下:
- <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-3.2.xsd">
- <beans profile="test">
- <bean id="datasource"
- class="org.Springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
- <property name="url" value="jdbc:hsqldb:hsql://localhost" />
- <property name="username" value="sa"/>
- <property name="password" value=""/>
- </bean>
- </beans>
- <beans profile="production">
- <bean id="datasource"
- class="org.Springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
- <property name="url" value="jdbc:hsqldb:hsql://localhost/prod" />
- <property name="username" value="sa"/>
- <property name="password" value=""/>
- </bean>
- </beans>
- <beans profile="test,production">
- <bean id="transactionManager"
- class="org.Springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="datasource"></property>
- </bean>
- <bean id="initer" init-method="init" class="service.Initializer">
- </bean>
- <bean id="accountDao" depends-on="initer" class="DAO.AccountDao">
- <property name="dataSource" ref="datasource"/>
- </bean>
- <bean id="accountService" class="service.AccountService">
- </bean>
- <bean id="envSetter" class="EnvSetter"/>
- </beans>
- </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 中都是一样的
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration("/config/Spring-db.xml")
- @Transactional
- @ActiveProfiles("test")
- public class AccountServiceTest {
- ...
- }
注意上面的 @ActiveProfiles,可以指定一个或者多个 profile,这样我们的测试类就仅仅加载这些名字的 profile 中定义的 bean 实例。
下面看一个配置实例:
添加依赖:
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.10</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>4.0.1.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.0.1.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>4.0.1.RELEASE</version>
- </dependency>
spring配置: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:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd"
- default-lazy-init="false">
- <description>Spring公共配置 </description>
- <context:component-scan base-package="cn.slimsmart.unit.test.demo" />
- </beans>
AddServiceImpl添加@service注解
测试类:
- package cn.slimsmart.unit.test.demo.junit;
- import static org.junit.Assert.assertTrue;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.test.context.ActiveProfiles;
- import org.springframework.test.context.ContextConfiguration;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
- import org.springframework.test.context.transaction.TransactionConfiguration;
- import org.springframework.transaction.annotation.Transactional;
- //用来说明此测试类的运行者,这里用了 SpringJUnit4ClassRunner
- @RunWith(SpringJUnit4ClassRunner.class)
- //指定 Spring 配置信息的来源,支持指定 XML 文件位置或者 Spring 配置类名
- @ContextConfiguration(locations = { "classpath*:/applicationContext.xml" })
- //表明此测试类的事务启用,这样所有的测试方案都会自动的 rollback,
- //@Transactional
- //defaultRollback,是否回滚,默认为true
- //transactionManager:指定事务管理器一般在spring配置文件里面配置
- //@TransactionConfiguration(defaultRollback=true,transactionManager="transactionManager")
- //但是需要兼容生产环境的配置和单元测试的配置,那么您可以使用 profile 的方式来定义 beans,
- //@ActiveProfiles("test")
- public class JunitSpringTest {
- @Autowired
- private AddService addService;
- @Before
- public void setUp(){
- System.out.println("初始化");
- }
- @Test
- public void testAdd() {
- assertTrue(addService.add(1, 1) == 2);
- }
- @After
- public void destroy() {
- System.out.println("退出,资源释放");
- }
- }
Junit 之 与Spring集成的更多相关文章
- Spring系列之新注解配置+Spring集成junit+注解注入
Spring系列之注解配置 Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率 你本来要写一段很长的代码来构造一个 ...
- 使用CXF与Spring集成实现RESTFul WebService
以下引用与网络中!!! 一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...
- elasticsearch spring 集成
elasticsearch spring 集成 项目清单 elasticsearch服务下载包括其中插件和分词 http://download.csdn.net/detail/u0142011 ...
- RabbitMQ安装和使用(和Spring集成)
一.安装Rabbit MQ Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装Rabbit MQ的前提是安装Erlang.通过下面两个连接下载安装3.2.3 版本: 下载并安装 E ...
- SSM框架开发web项目系列(五) Spring集成MyBatis
前言 在前面的MyBatis部分内容中,我们已经可以独立的基于MyBatis构建一个数据库访问层应用,但是在实际的项目开发中,我们的程序不会这么简单,层次也更加复杂,除了这里说到的持久层,还有业务逻辑 ...
- 消息中间件系列四:RabbitMQ与Spring集成
一.RabbitMQ与Spring集成 准备工作: 分别新建名为RabbitMQSpringProducer和RabbitMQSpringConsumer的maven web工程 在pom.xml文 ...
- Spring集成MyBatis的使用-使用SqlSessionTemplate
Spring集成MyBatis的使用 Spring集成MyBatis,早期是使用SqlSessionTemplate,当时并没有用Mapper映射器,既然是早期,当然跟使用Mapper映射器是存在一些 ...
- Spring集成MyBatis的使用-使用Mapper映射器
Spring集成MyBatis使用 前面复习MyBatis时,发现在测试时,需要手动创建sqlSessionFactory,Spring将帮忙自动创建sqlSessionFactory,并且将自动扫描 ...
- Spring集成Mybatis,spring4.x整合Mybatis3.x
Spring集成Mybatis,spring4.x整合Mybatis3.x ============================== 蕃薯耀 2018年3月14日 http://www.cnblo ...
随机推荐
- struts2的java.lang.NoSuchMethodException错误
不久前在学习struts时出现这个错误,在网上搜索了半天,发现答案不一.将其总结如下,以方便大家参考. 1. 你有没有试试看 其它的方法能不能用,要是都是这种情况的话,可能是你的Action类没有继承 ...
- How to change Eclipse loading image
Eclipse IDE has many customize components, the splash welcome image (purple color loading image) is ...
- List GroupBy真实用法,Reflection(反射)用法,Enum用法,正则,搜索下拉布局
1.List GroupBy 用法 var _roomProducts = homesingProducts.GroupBy(t => t.RoomName); RoomedProducts ...
- __x__(30)0908第五天__导航条的练习 <div>版本
效果图: html源代码: <!doctype html> <html> <head> <meta charset="utf-8" /& ...
- HDFS的WEB页面访问常见问题
HDFS的WEB UI管理页面 50070 端口 无法访问解决办法! 本文基于HADOOP-3..1.0,Cecntos7.0环境下进行测试,所以遇到很多新鲜的问题: 特别注意:HaDoop3.0之前 ...
- 利用XPT2046制作一个电位器AD转换装置
XPT2046是一款四线制电阻触摸屏控制芯片,内含12位分辨率125KHz转换速率逐步逼近型A/D转换器,支持从1.5V到5.25V的低电压I/O接口. 所谓逐步逼近型,就是输入一个模拟量,其与100 ...
- Ubuntu软件安装与卸载
ubuntu软件安装与卸载 更新Ubuntu软件下载地址 1. 寻找国内镜像源 所谓的镜像源:可以理解为提供下载软件的地方,比如Android手机上可以下载软件的91手机助手:iOS手机上可以下载软件 ...
- Sql中获取表结构(字段名称,类型,长度,说明)
Sql中获取表结构(字段名称,类型,长度,说明) SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Descript ...
- js表单提交到后台对象接收
$.extend({ StandardPost:function(url,args){ var form = $("<form method='post' target='_blank ...
- 小甲鱼零基础python课后题 P21 020函数:内嵌函数和闭包函数
测试题 0.如果希望在函数中修改全局变量的值,应该使用什么关键字? 答:globe 1.在嵌套函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字? 答:nonlocal 2.pyth ...