PowerMock相关
来源:互联网 发布:广告投放算法好吃 编辑:程序博客网 时间:2024/04/26 18:45
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.
示例代码1:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MyClass.class})
public class StaticClassSampleTest {
@Test
public void testPrivateMethod() throws Exception {
// 模拟 private的方法
MyClass spy = PowerMockito.spy(new MyClass());
PowerMockito.doReturn(3).when(spy, "private_method", 1);
Assert.assertEquals(3, spy.test_private_method(1));
PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke("private_method", 1);
}
@Test
public void testStaticReturnMethod() throws Exception {
// 模拟 静态有返回值的方法
PowerMockito.mockStatic(MyClass.class);
Mockito.when(MyClass.static_return_method()).thenReturn(2);
Assert.assertEquals(2, MyClass.static_return_method());
}
@Test
public void testVoidMethod() throws Exception {
// 模拟 不执行void的方法
MyClass spy = PowerMockito.spy(new MyClass());
PowerMockito.doNothing().when(spy).void_method();
spy.void_method();
}
@Test
public void testStaticMethod1() throws Exception {
// 模拟 不执行没参数的静态void的方法
PowerMockito.mockStatic(MyClass.class);
PowerMockito.doNothing().when(MyClass.class, "static_void_method");
MyClass.static_void_method();
}
@Test
public void testStaticMethod2() throws Exception {
// 模拟 不执行带参数的静态void的方法
PowerMockito.mockStatic(MyClass.class);
PowerMockito.doNothing().when(MyClass.class, "staticMethod", "123");
MyClass.staticMethod("123");
PowerMockito.doNothing().when(MyClass.class, "staticMethod", Mockito.anyString());
MyClass.staticMethod("456");
}
}
class MyClass {
final private int private_method(int a) {
return a;
}
public int test_private_method(int a) {
return private_method(a);
}
public static int static_return_method() {
return 1;
}
void void_method() {
throw new IllegalStateException("should not go here");
}
public static void static_void_method() {
throw new IllegalStateException("should not go here");
}
public static void staticMethod(String a) {
throw new IllegalStateException(a);
}
}
示例代码2:
@RunWith(PowerMockRunner.class)
@PrepareForTest(MockFile.class)
public class MockFile {
@Test
public void testRegisterService2() throws Exception {
String s="F:/aa.txt";
File file=PowerMockito.mock(File.class);
// PowerMockito.whenNew(File.class).withArguments(s).thenReturn(file);
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(file);
PowerMockito.when(file.exists()).thenReturn(true);
File a=new File(s);
Assert.assertEquals(true, a.exists());
}
}
示例代码3:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
// 注意这里,这个是new FileInputStream所在的类
@PrepareForTest({ AA.class })
public class MockWhenNew {
@Test
public void test() throws Exception {
// 模拟数据流
File file = PowerMockito.mock(File.class);
FileInputStream is = PowerMockito.mock(FileInputStream.class);
PowerMockito.whenNew(FileInputStream.class).withArguments(file).thenReturn(is);
InputStreamReader ir = new InputStreamReader(new ByteArrayInputStream("123".getBytes()));
PowerMockito.whenNew(InputStreamReader.class).withArguments(Mockito.any(FileInputStream.class)).thenReturn(ir);
AA spy = new AA();
Assert.assertEquals("123", spy.aa(file));
}
}
class AA {
public String aa(File file) throws Exception {
FileInputStream in = new FileInputStream(file);
InputStreamReader is = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(is);
String line = "", s = "";
while ((line = reader.readLine()) != null) {
s += line;
}
return s;
}
}
- PowerMock相关
- powermock
- powermock
- powermock
- PowerMock用法
- PowerMock介绍
- PowerMock介绍
- PowerMock介绍
- PowerMock介绍
- PowerMock 简介
- PowerMock使用
- PowerMock详解
- PowerMock概述
- PowerMock介绍
- PowerMock介绍
- PowerMock实践
- Mocking static methods (PowerMock )
- 浅谈EasyMock和PowerMock
- Getting “org.hibernate.TransactionException: nested transactions not supported” error when deleting
- 《C++ Primer Plus(第六版)》(36)(第十六章 string类和标准模板库 编程练习和答案)
- Android网络——Http通信
- 奥塔在线:如何查看连接数?
- 安卓开发遇到的几个问题(网络定位,从网络获取所有省/市,SQLite,Service等)
- PowerMock相关
- Android录屏——屏幕录制命令screenrecord
- 【Android图像处理】图像处理之-油画效果
- 数据结构(十六) 线索二叉树讲解(带头节点后序加线索) 以及实现的完整代码
- idea 必备插件之键盘流篇
- Android Gson @SerializedName注解
- GIS就业参考系列之修炼篇——这里的黎明静悄悄
- [FUNC]RunOrActivate
- 2017 第一篇博客