JMockit Mock 私有方法和私有属性
来源:互联网 发布:4种九九乘法表编程数组 编辑:程序博客网 时间:2024/05/06 12:31
JMockit Mock 私有方法和私有属性
前面说过 JMockit 因身处前线,所以简直无不可,本节例子演示 JMockit 怎么 Mock 私有方法和私有属性,示例虽然是静态方法和属性,但因采用的是反射手法,所以这种 Deencapsulation 的 Mock 手段同样适用于公有的方法或属性,无论是否静态。
本文所用 JMockit 版本为 1.6, 可能网上所搜索的方法与此有所不同,请注意 JMockit 版本差异。仍需重复一下,运行 JMockit 的例子 classpath 上必须让 jmockit.jar 在 junit.jar 之前,或用 javaagent 参数来加载 jmockit.jar,并且 junit 要 4.8 及以上版本.
1. Mock 私有方法(非静态类似)
package cc.unmi;public class MyService { public static String fetchData(String name){ System.out.println("call MyService.fetchData"); return fetchDataFromDB(name); } private static String fetchDataFromDB(String name){ throw new RuntimeException("Not implemented yet!"); }}
fetchDataFromDB 是私有静态方法,正常测试的话肯定不过
package cc.unmi;import mockit.Deencapsulation;import mockit.Expectations;import org.junit.Assert;import org.junit.Test;public class MyServiceTest { @Test public void testFetchData() { new Expectations(MyService.class) { { Deencapsulation.invoke(MyService.class, "fetchDataFromDB", "Unmi"); result = "http://unmi.cc"; } }; String actual = MyService.fetchData("Unmi"); Assert.assertEquals("http://unmi.cc", actual); }}
这行
Deencapsulation.invoke(MyService.class, "fetchDataFromDB", "Unmi");
使用了反射的方式拦截了 MyService 的 fetchDataFromDB 方法,并非强设了它的返回值为 “http://unmi.cc”。关键是调用了 Deencapsulation.invoke() 方法,来看到这个类里还有哪些方法:
看到上图,我们必须要产生一些想法的,特别是 invoke 和 setField,以及它们的第一个参数可以是 Class,也可以是 Object,不难获知的是我们能够借助于它来 Mocket 私有方法和属性,不论它们是静态还是非静态的。
上面的测试用例可以见绿,输出为:
call MyService.fetchData
本文原始链接 http://unmi.cc/jmockit-mock-private-methods-fields/ , 来自隔叶黄莺 Unmi Blog
如果把测试代码中的调用处改为
String actual = MyService.fetchData("Unmis");
测试将会失败:
java.lang.RuntimeException: Not implemented yet!
at cc.unmi.MyService.fetchDataFromDB(MyService.java:10)
at cc.unmi.MyService.fetchData(MyService.java:6)
at cc.unmi.MyServiceTest.testFetchData(MyServiceTest.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
................
对了,就是反射。受上面的点拨,怎么 Mock 属性已了然于心了,再行累述纯为拉长篇幅,不妨
2. Mock 私有属性(静态亦类似)
package cc.unmi;public class MyService { private String url = ""; public String fetchData(String name){ System.out.println("call MyService.fetchData"); return this.url; }}
欲 Mock 的是 url 属性,从 fetchData 方法的 return url 可以检测到 Mock 后的值
package cc.unmi;import mockit.Deencapsulation;import mockit.Expectations;import org.junit.Assert;import org.junit.Test;public class MyServiceTest { @Test public void testFetchData() { final MyService service = new MyService(); new Expectations() { { Deencapsulation.setField(service, "url", "http://unmi.cc"); } }; String actual = service.fetchData("Unmi"); Assert.assertEquals("http://unmi.cc", actual); }}
断言成功,与 Mock 私有方法有所不同的是在 new Expectations() 的括号中可以留白了,也用不着设置 result 值了。
从资料上看 Deencapsulation 是后来引入的,原来好像是直接调用 Expectations 的 invoke, setField 方法来改变运行中的值。
记得当初我们用 @MockClass, @Mock, 再 Mockit.setUpMock() 三步曲来进行 Mock 操作,如今看来光 new Expectations() 这一招便可走遍天下。
本文链接 http://unmi.cc/jmockit-mock-private-methods-fields/ , 来自隔叶黄莺 Unmi Blog
- JMockit Mock 私有方法和私有属性
- Reflect获取私有属性和私有方法
- Python----伪私有属性和私有方法
- jmockit Deencapsulation 访问类的私有成员和方法
- python对象:访问私有属性和私有方法
- Objective-c - 私有属性和私有方法的应用
- iOS运行时runtime获取私有属性和强制更改私有属性,以及获取私有方法
- 私有变量和私有方法
- 私有变量和私有方法
- java反射访问私有属性和方法
- 使用反射调用私有属性和方法
- javaScript中私有属性和方法
- PHPUnit测试私有属性和方法
- js--属性和方法(私有/公有)
- python 类的私有属性和方法
- javascript实现私有属性私有方法
- python之私有属性及私有方法
- oc定义私有变量和私有属性
- sqlite操作语句
- 第11周项目2(1)-最大公约数
- Arduino的详细介绍(基于Mega2560)——SoftwareSerial Library
- 推送跳转
- 第11周项目2(2)-最大公约数
- JMockit Mock 私有方法和私有属性
- ios之UITextField使用技巧概述/代理过滤字符/按return隐藏键盘/通知等用法
- PAT 1001
- oracle SQL state [99999]; error code [17026]; 数字溢出
- 第十一周项目一:函数版星号图3
- java.lang.NullPointerException at org.apache.jsp.index_jsp._jspInit(index_jsp.java:22)
- 第十一周项目5当年第几天
- Hdu 4587 TWO NODES(割点)
- 优先级队列与堆排序