使用Powermock进行单元测试,以及常见问题的处理
1. 引言
在进行单元测试时,经常遇到被测方法依赖外部对象和环境,如需要数据库连接,网络通信依赖等,需要进行大量的初始化工作,这时可以采用powermock+mockito对被测对象进行模拟,通过录放的形式解决此类问题。
Mockito 是一个针对 Java 的单元测试模拟框架,它与 EasyMock 和 jMock 很相似,都是为了简化单元测试过程中测试上下文 ( 或者称之为测试驱动函数以及桩函数 ) 的搭建而开发的工具。
PowerMock 也是一个单元测试模拟框架,它是在其它单元测试模拟框架的基础上做出的扩展。通过提供定制的类加载器以及一些字节码篡改技巧的应用,PowerMock 现了对静态方法、构造方法、私有方法以及 Final 方法的模拟支持,对静态初始化过程的移除等强大的功能。
2. 使用实例
模拟接口返回
首先对接口进行mock,然后录制相关行为
InterfaceToMock mock = Powermockito.mock(InterfaceToMock.class)
Powermockito.when(mock.method(Params…)).thenReturn(value)
Powermockito.when(mock.method(Params..)).thenThrow(Exception)
设置对象的private属性
需要使用whitebox向class或者对象中赋值。
如我们已经对接口尽心了mock,现在需要将此mock加入到对象中,可以采用如下方法:
Whitebox.setInternalState(Object object, String fieldname, Object… value);
其中object为需要设置属性的静态类或对象。
模拟构造函数
注意解决出现的@PowerMockIgnore("javax.management.*")问题
对于模拟构造函数,也即当出现new InstanceClass()时可以将此构造函数拦截并替换结果为我们需要的mock对象。
注意:使用时需要加入标记:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ InstanceClass.class })
@PowerMockIgnore("javax.management.*")
Powermockito.whenNew(InstanceClass.class).thenReturn(Object value)
模拟静态方法
模拟静态方法类似于模拟构造函数,也需要加入注释标记。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ StaticClassToMock.class })
@PowerMockIgnore("javax.management.*")
Powermockito.mockStatic(StaticClassToMock.class);
Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)
模拟final方法
Final方法的模拟类似于模拟静态方法。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ FinalClassToMock.class })
@PowerMockIgnore("javax.management.*")
Powermockito.mockStatic(FinalClassToMock.class);
Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)
模拟静态类
模拟静态类类似于模拟静态方法。
使用spy方法避免执行被测类中的成员函数
如被测试类为:TargetClass,想要屏蔽的方法为targetMethod.
1) PowerMockito.spy(TargetClass.class);
2) Powemockito.when(TargetClass.targetMethod()).doReturn()
3) 注意加入
@RunWith(PowerMockRunner.class)
@PrepareForTest(DisplayMoRelationBuilder.class)
@PowerMockIgnore("javax.management.*")
参数匹配器
有时我们在处理doMethod(Param param)时,不想进行精确匹配,这时可以使用Mockito提供的模糊匹配方式。
如:
Mockito.anyInt(),Mockito.anyString()
处理public void型的静态方法
Powermockito.doNothing.when(T class2mock, String method, <T>… params>
3.常见问题
使用Powermock后会提示classloader错误
加入注解:
@PowerMockIgnore("javax.management.*")
Eclipse + junit4 + Emma 无法统计覆盖率情况
Emma问题导致,暂无处理方法。
使用Ant和HUTAF_LLT覆盖率插件出现的覆盖率无法统计情况
原因是对被统计类使用了PrepareForTest()注解,去掉该注解,不再进行被测类方法进行mock.
使用Powermock进行单元测试,以及常见问题的处理的更多相关文章
- PowerMock 简介--转载
原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-powermock/ EasyMock 以及 Mockito 都因为可以极大地简化单元测试的书 ...
- PowerMock简介
PowerMock 写单元测试可能有些难.有时仅仅为了可测试性的目标而不得不牺牲好的设计.通常可测试性和好的测试之间是一致的,但是并不总是如此.比如,由于现存框架的限制,final classes.m ...
- PowerMock
EasyMock 以及 Mockito 都因为可以极大地简化单元测试的书写过程而被许多人应用在自己的工作中,但是这 2 种 Mock 工具都不可以实现对静态函数.构造函数.私有函数.Final 函数以 ...
- Mockito 库、powermock扩展
转载:http://blog.csdn.net/kittyboy0001/article/details/18709685 Mockito 简介 Mockito 是目前 java 单测中使用比较流行的 ...
- Mockito简介(转)
Mockito 是目前 java 单测中使用比较流行的 mock 工具.其他还有 EasyMock,JMock,MockCreator,Mockrunner,MockMaker 及 PowerMock ...
- Apache DolphinScheduler 项目笔记 — 1. 问题定位和排查问题
导语: Yuanhao Ji 同学是<暑期 2021 - API 模块 UT 测试问题解决>项目负责人,本文记录了他是如何排查和定位问题. 1. 背景 问题:在部分 UT 中使用 Powe ...
- 使用MRUnit,Mockito和PowerMock进行Hadoop MapReduce作业的单元测试
0.preliminary 环境搭建 Setup development environment Download the latest version of MRUnit jar from Apac ...
- 单元测试不是梦,Android+PowerMock系列(1) —— 在Eclipse里搭建测试环境
单元测试不好搞阿,虽然从TDD角度出发,可测性强的代码很大程度上就代表着好的设计,但是有些情况也是没办法的,比如单例模式,比如Static方法,比如Final类,传统的Mock技术是没办法解决这些问题 ...
- PowerMock单元测试踩坑与总结
1.Mock是什么? 通过提供定制的类加载器以及一些字节码篡改技巧的应用,PowerMock 现了对静态方法.构造方法.私有方法以及 Final 方法的模拟支持,对静态初始化过程的移除等强大的功能. ...
随机推荐
- 用PHP生成随机数的函数
转自:http://www.jbxue.com/article/5034.html 介绍:在早期的php中生成一个随机字符串时,总是先创建一个字符池,然后用一个循环和mt_rand()或rand()生 ...
- 获取json对象长度的问题
平时,我们获取一些字符串或数组的长度的时候会使用length,例如: var str ="asdasd" console.log(str.length) //输出6 var arr ...
- 解决CxGrid Filter 后,通过 Dataset 循环时得出的结果与 Grid显示不同步的问题.
// 方案1: 强制cxgrid 使用 dataset的 Filter GridMaster.DataController.Filter.AutoDataSetFilter := True; /// ...
- Objective-C常用类型、对象、方法
结构体 NSRange range=NSMakeRange(8,10);从0数第八个元素开始长度为10: NSString *str=NSStringFormRange(range); NSLog(@ ...
- linux 输入子系统(4)---- input子系统的初始化
Input子系统的初始化函数为input_init(),如下: static int __init input_init(void) { int err; input_init_abs_bypass( ...
- 手把手教你写LKM rookit! 之 第一个lkm程序及模块隐藏(一)
唉,一开始在纠结起个什么名字,感觉名字常常的很装逼,于是起了个这<手把手教你写LKM rookit> 我觉得: 你们觉得:...... 开始之前,我们先来理解一句话:一切的操作都是系统调用 ...
- Wpf 简单制作自己的窗体样式
最近一直在搞wpf相关的东东,由于还在门外徘徊,所以第一篇blog写了简单的制作扁平化的wpf button样式,这一篇也简单的制作属于自己wpf 窗体的样式. 废话少说,下面就开始制作自己的窗体样式 ...
- wampserver安装后的基本配置
wampserver安装后的基本配置 1.WampServer的安装 下载好安装包后,你能在保存其文件夹中找到这样一个图标: 双击它,会弹出如下提示 提示信息:不要试图从Wamp5 1.x(x代表任意 ...
- EXTJS 4.2 资料 控件之checkboxgroup的用法(动态数据)
在开发中遇到两种情况:第一在新增窗体时,要动态加载CheckBox项:第二在修改时不但需要加载所有CheckBox项,还要并且选中之前新增时的选项 如图这是在修改页面的效果: 1.在新增窗体中动态加载 ...
- 基于Python+协程+多进程的通用弱密码扫描器
听说不想扯淡的程序猿,不是一只好猿.所以今天来扯扯淡,不贴代码,只讲设计思想. 0x00 起 - 初始设计 我们的目标是设计一枚通用的弱密码扫描器,基本功能是针对不同类型的弱密码,可方便的扩展,比如添 ...