1、使用main方法
  最早的测试方法一般是在类中增加main方法,然后在main方法中增加对每个方法的测试代码,如果要测其中一个,就屏蔽掉其他的测试代码,执行后,根据log的打印来判断测试是否成功
2、使用junit
  junit的出现,使得针对每个方法的单独测试成为可能,在junit中一般使用4.0后,基于注解,在@befor中初始化数据,在@after中恢复测试现场,然后@test注解标注每个测试案例,在测试案例中使用assert断言来判断测试是否成功,使用junit的好处是:
  1)、可以针对每个测试案例编写测试代码
  2)、可以仅运行指定测试案例或者批量运行所有测试案例
  3)、可以使用断言判断测试结果
  4)、必要时候可以提供测试报告
  但同时,在使用junit之后,仍然有许多问题需要解决
  1)对于百分之50以上的应用都是基于spring进行构建,在初始化@befor中我们需要加载spring的bean,意味着多个方法同时测试时候,spring容器被多次初始化
  2)需要硬编码手工获取bean
  3)数据库现场会被破坏,如果在测试方法中执行了数据库改写语句,我们不得不在随后的代码中还原现场,否则数据会被破坏
  4)不方便对数据库操作结果进行验证
3、使用spring-test框架
  使用junit之后残留的问题,如果我们整个框架使用spring,可以使用spring提供的测试框架spring-test进行解决,以下是一个spring-test的基本案例
@RunWith(SpringJUnit4ClassRunner.class) //指定测试用例的运行器 这里是指定了Junit4
@ContextConfiguration("classpath:applicationContext.xml")
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
@Transactional
public class TestUserDao {
@Autowired
private BaseDao<User, Long> userDao = null; @Test
@Rollback(true)//上面已经设置defaultRollback=true。这里其实可以不用写了
public void testModifyUser() {
User user = userDao.findById(2L);
System.out.println(user.getId());
user.setDisplayName("系统管理员4");
userDao.saveOrUpdate(user);
Assert.assertEquals(userDao.findById(2L).getDisplayName(), "系统管理员4");
}
}

我们可以看到一些spring-test的基本操作:

  1)使用RunWith指定使用spring-test来进行单元测试
  2)ContextConfiguration来确定从配置文件或者java文件读取bean,如果是配置文件:@ContextConfiguration("classpath:applicationContext.xml"),如果是从java类开始:@ContextConfiguration(classes = BaseSpringTest.class)
  3)对于从java类开始,我们需要从包扫描,获取所有注解,需要配置@ComponentScan("包名")
  4)在类上TransactionConfiguration配置测试的默认配置,如是否需要使用事物,回滚等
  5)基本类的注解与之前spirng的开发一致
  6)对于单个案例的测试和回滚,默认使用@Rollback和@Transactional进行标记
4、使用mock框架
  在测试过程中,不可避免的遇到比如我们要测试一个serivce,但是测试过程中会调用到dao层,而dao层需要访问数据库,或者需要引用到网络访问层,所有测试会影响到数据库或者依赖于外部网络环境,所以在测试过程中要求,对系统环境要求很高,这个时候,我们可以使用Mockito框架,进行模拟dao层或者网络访问层进行测试,如下实例:
public class SimpleTest {  

    @Test
public void simpleTest(){ //创建mock对象,参数可以是类,也可以是接口
List<String> list = mock(List.class); //设置方法的预期返回值
when(list.get(0)).thenReturn("helloworld"); String result = list.get(0); //验证方法调用(是否调用了get(0))
verify(list).get(0); //junit测试
Assert.assertEquals("helloworld", result);
}
}

  我们使用mock方法模拟了一个list,并将他的get(0)方法设定返回为"helloworld",如果有调用此方法时候,就会返回指定的调用值

  spring-test与mock结合的测试案例写法

public class MockSpringTest extends BaseSpringTest {  

    @Autowired
private OrderBefore orderBefore; @InjectMocks
private OrderCreate orderCreate = mock(OrderCreate.class); @Mock
private OrderHelper orderHelper; @Autowired
private OrderStart orderStart; @Before
public void initMocks() throws Exception {
MockitoAnnotations.initMocks(this); //对注解中的mock进行初始化
ReflectionTestUtils.setField(AopTargetUtils.getTarget(orderStart), "orderCreate", orderCreate); //AopTargetUtils为自定义的类,将属性注入到bean的方法内
doReturn(11).when(orderCreate).getAmt(); //定义方法默认返回
doReturn("success").when(orderHelper).resolve(); //定义方法默认返回
doCallRealMethod().when(orderCreate).create(); //定义方法调用真实方法
} @Test
public void create() {
System.out.println("start mock...");
//orderStart中注入了orderStart,orderStart中注入了orderCreate,
//如果按照正常写法,会调用orderCreate的getAmt方法,但是我们之前使用了setFiled将方法将orderStart的属性替换为了mock类,所以可以看到执行结果为11
orderBefore.before();
}
}
 

[spring源码学习]单元测试演化的更多相关文章

  1. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  2. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

  3. Spring源码学习

    Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...

  4. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  5. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  6. Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作

    写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...

  7. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  8. 【目录】Spring 源码学习

    [目录]Spring 源码学习 jwfy 关注 2018.01.31 19:57* 字数 896 阅读 152评论 0喜欢 9 用来记录自己学习spring源码的一些心得和体会以及相关功能的实现原理, ...

  9. Spring 源码学习——Aop

    Spring 源码学习--Aop 什么是 AOP 以下是百度百科的解释:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程通过预编译的方式和运行期动态代理实 ...

随机推荐

  1. 配置tomcat系统日志--java eclipse

    控制台那里的日志只是部分,有时候报错了我们并没有显示出来,所以需要找到系统日志... 双击tomcat v.80 Service---点击open lauch Configuration--Argum ...

  2. Java ClassLoader 原理详细分析(转)

    转载自:http://www.codeceo.com/article/java-classloader.html 一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管 ...

  3. [cocos] ( 01 ) cocos2d-x 3.x 开发 环境配置

    有几个需要注意的问题 Windows上使用时, Unable to execute dex: Multiple dex files define 在eclipse中libcoco2dx的Java Bu ...

  4. 面向对象Part2

    `变量: 成员变量:又叫全局变量,定义在类中,方法外面. 1).类成员变量.   使用Static 2).实例成员变量.  没有使用Static. 局部变量:出了成员变量,其他的都是局部变量. 1). ...

  5. neurosolutions 人工神经网络集成开发环境 keras

    人工神经网络集成开发环境 :  http://www.neurosolutions.com/ keras:   https://github.com/fchollet/keras 文档    http ...

  6. Angular2 NgModule

    1. 说明 典型的模块是一个内聚的代码块,用来实现某种单一的功能.Angular2应用程序本质上是有一系列模块组成的,而且Angular 本身就是一组模块库.模块主要是导出一些东西——类,函数,值,供 ...

  7. SAP 直营验单

    *&---------------------------------------------------------------------* *& Report  ZSDR005 ...

  8. 编译osgEarth2.8遇到gdal_vrt.h找不到的问题

    在编译plugins osgearth_gdal的ReaderWriterGDAL.cpp的时候可能会遇到这个问题 gdal_vrt.h这个头文件在gdal-1.11.0\frmts\vrt目录下,从 ...

  9. CSS3简易表盘时钟

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. MySQL延迟复制--percona-toolkit和MASTER TO MASTER_DELAY

    为了数据的安全,有的时候数据库需要延迟备份,这里说下两种延迟备份的方法. 一.借助工具. 实现环境: 192.168.189.143 (mysql主库) 192.168.189.144 (mysql备 ...