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
如果把測試程式碼中的呼叫處改為
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() 這一招便可走遍天下。
相關推薦
JMockit Mock 私有方法和私有屬性
前面說過 JMockit 因身處前線,所以簡直無不可,本節例子演示 JMockit 怎麼 Mock 私有方法和私有屬性,示例雖然是靜態方法和屬性,但因採用的是反射手法,所以這種 Deencapsulation 的 Mock 手段同樣適用於公有的方法或屬性,無論是否靜態。 本文所用 JMockit 版本為
python私有方法和私有屬性屬性理解
__init__ out code 避免 col 系統 import name sizeof 私有屬性、方法——Python並沒有真正的私有化支持,但可用下劃線得到偽私有盡量避免定義以下劃線開頭的變量 (1)_xxx "單下劃線 " 開始的成員變量叫做保護變量
Python中私有方法和私有屬性
Python 私有方法 私有屬性 1.私有方法和私有屬性私有方法只能在類內部被調用,不能被對象使用私有屬性只能在類內部使用,不能被對象使用 私有屬性只能在類內部使用,對象不能使用,但是,我們可以通過在類內部定義公有方法對私有屬性進行調用或修改,然後對象在調用這個公有方法使用。###私有屬性和私有方
python私有方法和私有屬性
Python預設的成員函式和成員變數都是公開的,Python 私有屬性和方法沒有類似別的語言的public,private等關鍵詞來修飾。 在python中定義私有變數只需要在變數名或函式名前加上 "__"兩個下劃線,那麼這個函式或變數就會為私有的了宣告該方法為私有方法,不能在類的外部呼叫
為什麼說 Objective-C 沒有私有方法和私有變數
首先,我們先來看一下私有的定義:私有是指只能夠在本類內部使用或訪問,但是不能在類的外部被訪問。 看起來好像沒有什麼問題,不過以下的幾種方式的確打破了上面的規則。 訪問私有方法 在 Objective-C 中,物件呼叫方法是以傳送訊息的形式實現的。所有方法的呼叫最終都會轉化為傳送訊息的形式,原型如下:
通過反射訪問任意類的私有方法和屬性
給出一個如下類: package test2; public class MathDemo { private int m = 10; private MathDemo(){ } private int add(int a,i
Python的程序結構(2) -> 方法/Method -> 類實例方法、私有方法和抽象方法
模塊 魔術 程序 技術 pytho 將不 abs 保護 error 類實例方法、私有方法和抽象方法 Python中最常用的就是類實例方法,類似於屬性中的類實例屬性,同時,也存在與私有屬性類似方法,即私有方法,下面介紹這兩種常見的方法,以及一種特殊意義的類實例方法 -- 抽
python 類的私有變數和私有方法介紹
版權宣告:博主原創文章,轉載請註明來源,謝謝合作!! https://mp.csdn.net/mdeditor/84438578 預設情況下,Python中的成員函式和成員變數都是公開的(public),在python中沒有類似public,private等關鍵詞來修飾成員
Java Reflection(七):私有變數和私有方法
原文地址 作者: Jakob Jenkov 譯者:葉文海([email protected]) 內容索引 訪問私有變數 訪問私有方法 在通常的觀點中從物件的外部訪問私有變數以及方法是不允許的,但是Java反射機制可以做到這一點。使用這個功能並不困難,在進行單元測試時這個功能非常有效。
使用powerMock和mockito模擬靜態方法和私有方法
首先我們要匯入相應的包 <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artif
Java 反射建立類的例項物件(預設構造方法和私有構造方法)
反射之建立類的例項物件 通過反射可以建立Class<?>中”?”對應的型別的例項物件,眾所眾知,建立類物件,會呼叫構造方法,構造器可以有多個,預設構造方法,多引數構造方法等。 這裡演示,通過反射建立預設構造方法的例項物件,和帶引數的構造方法的例項
iOS開發私有變數和私有方法
oc中有私有變數,沒有私有犯法,但是嚴格來說沒有絕對的私有變數和私有方法 私有變數: oc中提供了關鍵字@private來宣告私有變數,只允許本類訪問 私有方法: oc中沒有提供關鍵字來宣告私有方法,可以通過catogry的匿名類E
Java 私有變數和私有方法
作者: Jakob Jenkov 譯者:葉文海([email protected]) 內容索引 訪問私有變數訪問私有方法 在通常的觀點中從物件的外部訪問私有變數以及方法是不允許的,但是 Java 反射機制可以做到這一點。使用這個功能並不困難,在進行單元測試時這個功能非常有效。本節會向你展示如何
利用java反射機制,實現對類的私有變數和私有方法的訪問
記得有一句很有名的話:No reflection ,no frameworks 這一句短短的話道出了java 反射機制的強大。 java關於反射機制的包主要在java.lang.reflect中,structs,hibernate,spring等框架都是基於java的反射機制。 下面是一個關於利用j
python中的例項方法、靜態方法、類方法、私有方法和保護方法
例項方法: 例項方法顧名思義就是例項物件呼叫的方法,是最普遍最常用的類中的方法: class animal(object): def __init__(self): pass def talk(self):
Vue2.x源碼學習筆記-Vue靜態方法和靜態屬性整理
temp next 技術 spa delet 結構 又是 靜態 https Vue靜態方法和靜態屬性,其實直接在瀏覽器中可以查看到的,如下 圈起來的是其靜態屬性,但是有的屬性對象中的屬性的值又是函數。未圈起來的則是函數。 其實它來自如下各個目錄下的js文件 // src
php中靜態方法和靜態屬性的介紹
靜態屬性 size col 實例 生效 訪問類 都是 靜態 self 靜態分為兩個部分:靜態屬性和靜態方法 靜態的東西都是給類用的(包括類常量),非靜態的都是給對象用的 靜態屬性 在定義屬性的時候,使用關鍵字static修飾的屬性稱之為靜態屬性。 靜態方法 使用sta
python進階之類常用魔法方法和魔法屬性
sdn 主程序 都是 執行 pre 直接 內部 __main__ == 前言 前面我們總結過了python的關鍵字、運算符、內置函數、語法糖等與python魔法方法之間的關系,現在我們更細一點,看看python的面向對象編程有哪些常用的魔法屬性和魔法方法。 魔法屬性 對於一
ES6 - 類的靜態方法和靜態屬性
一、靜態方法 類的所有方法都定義在類的prototype屬性上面,所有類中定義的方法都會被例項繼承,如果在類方法前面加上static關鍵字就不會被例項繼承了。 靜態方法是直接通過類名來呼叫。 class Person{ constructor(name="xf",age){ t
十二、python學習之python高階二(property、魔法方法和魔法屬性、多繼承和多重繼承、閉包和裝飾器)
一、property: 1.get/set方法: 1.1 隱藏實現細節:在使用物件時,儘量不要讓使用者直接操作物件中的屬性,這樣會帶來安全隱患。改進辦法,使用私有屬性。 1.2 提供精確的訪問控制:學習過 set/get方法,是專門來為類的私有屬性提供訪問介面。 1.