Spring单元测试
1.基于AbstractDependencyInjectionSpringContextTests
Spring的单元测试可以使用AbstractDependencyInjectionSpringContextTests做测试,不支持事务。AbstractTransactionalDataSourceSpringContextTests是支持事务的。
Spring单元测试需要注意的地方:
(1)需要注入的类内成员如果不是public类型,需要定义setter方法才能正常注入(针对在Spring配置中不重复的类,如果重复出现则需要使用getBean方法);
(2)需要引入Spring-test.jar到工程,才能继承该测试类;
(3)默认的classpath在WEB-INF/classes/目录下,如果Spring配置文件不在该目录下需要指定位置(设置classpath或者使用项目根目录);
(4)如果测试类比较多,可以使用一个公共的测试基类完成注入的工作。
(5) 需要一个getConfigLocations方法指定配置文件路径。
public class Test extends AbstractDependencyInjectionSpringContextTests {
@Autowired
private PersonService personService;
public PersonService getPersonService() {
return personService;
}
protected String[] getConfigLocations() {
String[] configs = new String[] { "/Iocbean.xml"};
return configs;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
public void test(){
personService.save();
}
}
2.基于JUnit的测试
单元测试目前主要的框架包括 Junit、TestNG,还有些 MOCK 框架,例如 Jmock、Easymock、PowerMock 等。
public class AOPTestJunit {
private AService aService;
private ApplicationContext ctx;
public AService getaService() {
return aService;
}
public void setaService(AService aService) {
this.aService = aService;
}
@Before
public void setUp() throws Exception {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@After
public void tearDown() throws Exception {
}
@Test
public void test() {
System.out.println("SpringTest JUnit test");
aService = (AService) ctx.getBean("aService");
aService.fooA("JUnit test fooA");
aService.barA();
}
}
3.基于注解的方式
第2中方法的测试类中,我们还不能使用 Spring 的注解方式,会出现空指针异常,要实现注解方式的自动注入要使用如下的方式。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-jms.xml")
@Transactional
public class ProducerConsumerTest { @Autowired
private ProducerService producerService;
@Autowired
@Qualifier("queueDestination")
private Destination destination; @Test
public void testSend() {
for (int i=0; i<2; i++) {
producerService.sendMessage(destination, "你好,生产者!这是消息:" + (i+1));
}
} }
对标签的解释:
@RunWith 注释标签是 Junit 提供的,用来说明此测试类的运行者,这里用了 SpringJUnit4ClassRunner,这个类是一个针对 Junit 运行环境的自定义扩展,用来标准化在 Spring 环境中 Junit的测试用例,例如支持的注释标签。
@ContextConfiguration 注释标签是 Spring test context 提供的,用来指定 Spring 配置信息的来源,支持指定 XML 文件位置或者 Spring 配置类名,这里我们指定 classpath 下的 /spring-jms.xml 为配置文件的位置。
@Transactional 注释标签是表明此测试类的事务启用,这样所有的测试方案都会自动的 rollback,即不用自己清除自己所做的任何对数据库的变更了。
一些常见的基于 Junit4 的注释标签在 Spring 测试环境中的使用方法:
@Test(expected=...)
此注释标签的含义是,这是一个测试,期待一个异常的发生,期待的异常通过 xxx.class 标识。例如,我们修改 AccountService.Java 的 insertIfNotExist 方法,对于传入的参数如果为空,则抛出 IllegalArgumentException,如下:
public void insertIfNotExist(Account account) {
if(account==null)
throw new IllegalArgumentException("account is null");
Account acct = accountDao.getAccountById(account.getId());
if(acct==null) {
log.debug("No "+account+" found,would insert it.");
accountDao.saveAccount(account);
}
acct = null;
}
然后,在测试类中增加一个测试异常的方法,如下:
@Test(expected=IllegalArgumentException.class)
public void testInsertException() {
service.insertIfNotExist(null);
}
运行结果是 green bar。
@Test(timeout=...)
可以给测试方法指定超时时间(毫秒级别),当测试方法的执行时间超过此值,则失败。
比如在 AccountService 中增加如下方法:
public void doSomeHugeJob() {
try {
Thread.sleep(2*1000);
} catch (InterruptedException e) {
}
}
上述方法模拟任务执行时间 2 秒,则测试方法如下:
@Test(timeout=3000)
public void testHugeJob() {
service.doSomeHugeJob();
}
上述测试方法期待 service.doSomeHugeJob 方法能在 3 秒内结束,执行测试结果是 green bar。
@Repeat
通过 @Repeat,您可以轻松的多次执行测试用例,而不用自己写 for 循环,使用方法:
@Repeat(3)
@Test(expected=IllegalArgumentException.class)
public void testInsertException() {
service.insertIfNotExist(null);
}
这样,testInsertException 就能被执行 3 次。
Spring单元测试的更多相关文章
- SSM_CRUD新手练习(7)Spring单元测试分页请求
好久没写这个系列博客了是因为本人去公司实习去了,公司用的是Spring+SpingMvc+Hibernate现在有时间了不管怎么样继续把这个项目写完. 因为机器的原因,我的环境变成了IDEA+orac ...
- SSM搭建Spring单元测试环境
原文链接:https://jingyan.baidu.com/article/93f9803f5a97a4e0e46f55c8.html SSM搭建Spring单元测试环境
- 五、Spring ——单元测试
1.JUnit4 JUnit测试用例的完整生命周期要经历一下阶段:类级初始化资源处理,方法级初始化资源处理.执行测试用例中的方法.方法级销毁资源处理.类级销毁资源处理. 测试方法 @Test 初始化 ...
- Spring错误——Spring 单元测试——Test class should have exactly one public constructor
背景:Spring 构建单元测试 错误 java.lang.Exception: Test class should have exactly one public constructor at or ...
- Spring 单元测试 RequestContextHolder.getRequestAttributes()).getRequest(); 为空的原因
原因是因为单元测试时没有加载 web.xml 中的: <!-- spring在service层获取session和request需要创建的监听器 --> <listener> ...
- spring单元测试报错:Failed to load ApplicationContext 的解决方法
使用idea 配置单元测试之后,配置完spring的注解@junit 和@runer 之后 一直报错. 最后发现是默认使用jdk1.8引起的,使用jdk1.7即可.
- 当spring单元测试需要用到临时表的时候
需要将整个单元测试的方法交给spring的事务管理器控制. 两种解决方法: 1.加载的spring配置文件中advice要切到需要测试的方法. 2.单元测试类继承AbstractTransaction ...
- Maven项目 Spring 单元测试
使用maven创建web工程,将Spring配置文件applicationContext.xml放在src/resource下,用eclipse编译时提示class path resource [ap ...
- 整合Spring+Struts2+Mybatis加spring单元测试等
前言 自己是在CentOS7的IntelliJ IDEA里开发的,里面中文输入法有问题经常用不了,所以这里用了很多chinglish,希望不要介意: 一:pom依赖 <?xml version= ...
随机推荐
- c++工程重复编译与重复定义
#ifndef #define #endif防止的是"重复编译",而不是"重复定义"重复编译可能造成重复定义,但重复定义的来源不只有重复编译从代码变成可执行的程 ...
- 《你不知道的JavaScript上卷》知识点笔记
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC" } p.p2 { margin: 0.0px ...
- Unity LayerMask
Unity用int32的每一位表示32个层,int32用二进制有32位,Layers通常被摄像机用来渲染部分场景,和灯光照射部分场景使用.但是它们也可以用来做射线检测时忽略一些collder或Coll ...
- .29-浅析webpack源码之Resolver.prototype.resolve
在上一节中,最后返回了一个resolver,本质上就是一个Resolver对象: resolver = new Resolver(fileSystem); 这个对象的构造函数非常简单,只是简单的继承了 ...
- 微信公众号中ip白名单用谁的ip
https://segmentfault.com/q/1010000010201211 白名单怎么说 我该填写谁的 我的ip地址每天都变化的 服务器ip啊,为了防止未授权的代码盗用你的权限.写你ip是 ...
- J.U.C CAS
在JDK1.5之前,也就是J.U.C加入JDK之前,Java是依靠synchronized关键字(JVM底层提供)来维护协调对共享字段的访问,保证对这些变量的独占访问权,并且以后其他线程忽的该锁时,将 ...
- hashCode方法和equals方法比较
为什么用HashCode比较比用equals方法比较要快呢?我们要想比较hashCode与equals的性能,得先了解HashCode是什么. HashCode HashCode是jdk根据对象的地址 ...
- Centos硬盘IO性能检测命令iostat[转]
Centos硬盘IO性能检测命令iostat[转] 在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching.这个问题,貌似有不少人在问,不过都 ...
- linux_nginx反向代理
什么代理? 代理他人工作 什么是正向代理和反向向代理,他们之间的区别? 这两个代理很类似,但扮演了两个不同角色,一个站在用户角度,一个站在服务端角度 正向代理: 帮助用户请求服务 返向代理:帮助服务均 ...
- 11_什么是sql注入?
什么是sql注入? --因为后台会把用户输入的插入到后台的sql语句中,来进行sql查询判断用户输入是否存在数据库中, 来验证用户是否合法,就会出现一个问题,用户在做用户验证的时候,在输入框注 ...