日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java mock私有方法_JMockit Mock 私有方法和私有属性

發布時間:2024/1/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java mock私有方法_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!");

}

}

1

2

3

4

5

6

7

8

9

10

11

12

packagecc.unmi;

publicclassMyService{

publicstaticStringfetchData(Stringname){

System.out.println("call MyService.fetchData");

returnfetchDataFromDB(name);

}

privatestaticStringfetchDataFromDB(Stringname){

thrownewRuntimeException("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);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

packagecc.unmi;

importmockit.Deencapsulation;

importmockit.Expectations;

importorg.junit.Assert;

importorg.junit.Test;

publicclassMyServiceTest{

@Test

publicvoidtestFetchData(){

newExpectations(MyService.class){

{

Deencapsulation.invoke(MyService.class,"fetchDataFromDB","Unmi");

result="http://unmi.cc";

}

};

Stringactual=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

如果把測試代碼中的調用處改為

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;

}

}

1

2

3

4

5

6

7

8

9

10

11

packagecc.unmi;

publicclassMyService{

privateStringurl="";

publicStringfetchData(Stringname){

System.out.println("call MyService.fetchData");

returnthis.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();

Deencapsulation.setField(service, "url", "http://unmi.cc");

String actual = service.fetchData("Unmi");

Assert.assertEquals("http://unmi.cc", actual);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

packagecc.unmi;

importmockit.Deencapsulation;

importmockit.Expectations;

importorg.junit.Assert;

importorg.junit.Test;

publicclassMyServiceTest{

@Test

publicvoidtestFetchData(){

finalMyServiceservice=newMyService();

Deencapsulation.setField(service,"url","http://unmi.cc");

Stringactual=service.fetchData("Unmi");

Assert.assertEquals("http://unmi.cc",actual);

}

}

斷言成功,也用不著設置 result 值了, 而且這時候也用不著 new Expectations()? 了。

Deencapsulation 是后來引入的,在 JMockit 0.999.19 中可以在? Expectations 中直接調用 invoke, setField 方法來改變運行中的值,Expectations 繼承自 Invocations,原來的 Invocations 中定義了 invoke, setField, getFiled 等方法,新版的 JMockit 從? Invocations 中移除了那些方法。

記得當初我們用 @MockClass, @Mock, 再 Mockit.setUpMock() 三步曲來進行 Mock 操作,如今看來光 new Expectations() 這一招便可走遍天下。

總結

以上是生活随笔為你收集整理的java mock私有方法_JMockit Mock 私有方法和私有属性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。