转载:http://www.blogjava.net/qileilove/archive/2014/03/07/410713.html
1.关键词
  单元测试、spring、mockito
  2.概述
  单元测试目前已经成为项目中保证代码质量的一种必要方法,对于一些不易构造或者不易获取的对象通过mock的方式进行测试是一种很有效的处理办法。在基于spring的mock测试中,mock对象获取和使用的便利性可以提升单元测试代码的质量。
  3.实现原理
  Mock对象的注入使用注解和反射,对象注入依赖spring框架支持junit4提供的TestExcutionListeners监听器对象,在监听器中将mock对象注入到单元测试类中。
  4.新建对象方式代码
private IAccessServiceaccessService = Mockito.mock(IAccessService.class);
@BeforeClass
public static void beforeClass(){
// 构造并注入Mock对象ICmsProxyService
sceneConfigService.setAccessService(accessService);
}
  5.监听器方式代码
  5.1  实现监听器
  继承DependencyInjectionTestExecutionListener类,
  实现injectDependencies(TestContexttestContext)方法
public class MockitoDependencyInjectionTestExecutionListener extends
DependencyInjectionTestExecutionListener {
@Override
protected void injectDependencies(TestContext testContext) throws Exception {
super.injectDependencies(testContext);
init(testContext);
}
  5.2 利用反射注入mock对象
private void init(final TestContext testContext)throws Exception {
Object bean = testContext.getTestInstance();
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if(annotationinstanceof Mock){
//注入Mock实例
MockObject obj = new MockObject();
obj.setType(field.getType());
obj.setObj(Mockito.mock(field.getType()));
field.setAccessible(true);
field.set(bean, obj.getObj());
mockObjectMap.put(field.getName(), obj);
}else if(annotation instanceofAutowired){
injectFields.add(field);
}
}
}
AutowireCapableBeanFactory factory =testContext.getApplicationContext().getAutowireCapableBeanFactory();
//Autowired注解注入mock对象
for (Field field :injectFields) {
field.setAccessible(true);
Object object = field.get(bean);
if(objectinstanceof Proxy){
Class targetClass = AopUtils.getTargetClass(object);
if(targetClass ==null)
return;
Field[] targetFields =targetClass.getDeclaredFields();
for(Field targetField : targetFields){
targetField.setAccessible(true);
if(mockObjectMap.get(targetField.getName()) ==null){
continue;
}
targetField.set(getTargetObject(object,mockObjectMap.get(targetField.getName()).getType()),mockObjectMap.get(targetField.getName()).getObj());
}
}else{
Object realObject = factory.getBean(field.getName());
if(null != realObject){
Method[] methods = realObject.getClass().getDeclaredMethods();
for (Method method : methods) {
if(method.getName().equalsIgnoreCase("set" +field.getName())){
method.invoke(realObject, mockObjectMap.get(field.getName()).getObj());
}
}
}
}
}
}
  5.3 测试类配置
  使用@TestExecutionListeners注解,引入监听器,需要mock的对象加上@Mock注解。
@TestExecutionListeners({MockitoDependencyInjectionTestExecutionListener.class})
public class AccessServiceImplTest extends BaseTestCase{
@Autowired
private IAccessServiceaccessService;
@Mock
private IPersonServicepersonService;
@Mock
private IAccessDaoaccessDao;
}
  6.总结
  监听器的方式解放了代码中硬编码注入mock对象,使得代码简洁干净。

基于spring与mockito单元测试Mock对象注入的更多相关文章

  1. 在SpringTest中将Mockito的mock对象通过spring注入使用

    转载:https://blog.csdn.net/m0_38043362/article/details/80111957 1. 原理介绍 通过BeanFactoryPostProcessor向Bea ...

  2. 教育单元测试mock框架优化之路(上)

    转载:https://sq.163yun.com/blog/article/169561874192850944 众所周知,mock对于单元测试,尤其是基于spring容器的单元测试,是非常重要的.它 ...

  3. 一文让你快速上手 Mockito 单元测试框架

    前言 在计算机编程中,单元测试是一种软件测试方法,通过该方法可以测试源代码的各个单元功能是否适合使用.为代码编写单元测试有很多好处,包括可以及早的发现代码错误,促进更改,简化集成,方便代码重构以及许多 ...

  4. Spring Boot中采用Mockito来mock所测试的类的依赖(避免加载spring bean,避免启动服务器)

    最近试用了一下Mockito,感觉真的挺方便的.举几个应用实例: 1,需要测试的service中注入的有一个dao,而我并不需要去测试这个dao的逻辑,只需要对service进行测试.这个时候怎么办呢 ...

  5. Spring学习12-Spring利用mock进行单元测试

    一.概述    对于Java组件开发者来说,他们都盼望拥有一组能够对组件开发提供全面测试功能的好用的单元测试.一直以来,与测试独立的Java对象相比,测试传统型J2EE Web组件是一项更为困难的任务 ...

  6. spring boot的对象注入

    1 需求 现在我们的项目中需要引入一个java类库,我想要很方便的使用该类库中的一个类,并且我想要创建这个类的一个单例对象.然后可以很方便的在各个模块中用@AutoWired进行对象注入. 比如一个配 ...

  7. spring:为javabean的集合对象注入属性值

    spring:为JavaBean的集合对象注入属性值 在 spring 中可以对List.Set.Map 等集合进行配置,不过根据集合类型的不同,需要使用不同的标签配置对应相应的集合. 1.创建 Ts ...

  8. spring练习,使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打印输出。

    相关 知识 >>> 相关 练习 >>> 实现要求: 使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打印输出.要求如下: ...

  9. 基于Spring DM管理的Bundle获取Spring上下文对象及指定Bean对象

    在讲述服务注册与引用的随笔中,有提到context.getServiceReferences()方法,通过该方法可以获取到OSGI框架容器中的指定类型的服务引用,从而获取到对应的服务对象.同时该方法还 ...

随机推荐

  1. svn 迁移到 git 仓库并保留 commit 历史记录

    1.svn 转换为 git(会提示,让你输入先前 svn 的账号与密码) # 切换至 本地项目目录 cd /Users/jianbao/PhpStormProjects/fiisoo/ # 克隆 sv ...

  2. perl数组高级

    1 去除一个数组中的重复元素: 使用grep函数代码片段: 代码: my @array = ( 'a', 'b', 'c', 'a', 'd', 1, 2, 5, 1, 5 ); my %count; ...

  3. java ffmpeg视频转码(自测通过)

    import java.io.*; public class VideoTransfer { //ffmepg文件 安装目录 private static String ffmpeg = " ...

  4. MAC系统压缩文件传到WINDOWS下出现乱码

    可能使用Mac系统的朋友,在压缩文件时遇到过这样的问题: 要给朋友传文件,而对方又是WIN系统.我们打好包传过去以后,对方解压缩发现中文文件名都成乱码了.这是怎么回事? 原来,Mac下,默认文字编码是 ...

  5. insert 语句后面不要跟 where 等条件语句

    insert 语句后面不要跟 where 等条件语句: update 才用得到.

  6. IntentService 与ResultReceiver

    from://http://lyzhanghai.iteye.com/blog/947504 在google的I/O大会中关于“Writing zippy Android apps”,有讲过用Inte ...

  7. Shell操作mysql数据库

    From : http://www.2cto.com/database/201306/220570.html Shell操作mysql数据库   mysql  -hhostname -Pport -u ...

  8. spring学习之@SessionAttributes

    一.@ModelAttribute 在默认情况下,ModelMap 中的属性作用域是 request 级别是,也就是说,当本次请求结束后,ModelMap 中的属性将销毁.如果希望在多个请求中共享 M ...

  9. spring boot1.5以上版本@ConfigurationProperties取消location注解后的替代方案 cannot resolve method location

    问题 在spring boot(版本1.5.1.RELEASE)项目中,当准备映射自定义的配置文件属性到类中的时候,发现原本的@ConfigurationProperties注解已将location属 ...

  10. 5.2 dubbo-compiler源码解析

    ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class); final P ...