![](/img/trans.png)
[英]How can I access private class members of container class within the anonymouse inner class?
[英]How can I access private class members in Java?
我有數據模型類,包含私有字段,這些字段是只讀的(通過getter函數)。 這些字段由我的JPA持久性提供程序(eclipselink)在正常操作期間使用數據庫的內容設置。 對於單元測試,我想將它們設置為來自持久層的模型的偽值。 我怎樣才能做到這一點? 無論如何,eclipselink如何設置這些值?
簡化示例:
@Entity
class MyEntity
{
@Id
private Integer _ix;
public Integer ixGet()
{
return this._ix;
}
}
你可以嘲笑實體本身,提供你自己的getter實現嗎?
您可以在模擬持久層中創建匿名擴展:
MyEntity x = new MyEntity() {
public Integer ixGet() { return new Integer(88); }
};
您需要使用Reflection API。 使用Class.getField()來獲取該字段,然后在該字段上調用setAccessable(true),以便您可以寫入它,即使它是私有的,最后您可以在其上調用set()來寫入新值。
例如:
public class A {
private int i;
}
您希望將字段“i”設置為3,即使它是私有的:
void forceSetInt(Object o, String fieldName, int value) {
Class<?> clazz = o.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(o, value);
}
您需要處理許多例外情況。
您可以使用像Mockito這樣的測試庫來以讀寫模式訪問對象內部狀態。 例如,使用Mockito:
//read
Integer i = Whitebox.getInternalState(myEntity,"_ix")
//Write
Whitebox.setInternalState(myEntity,"_ix", 123)
你可以通過封裝來使用像powermock這樣的模擬框架。 在powermock中,您將使用Whitebox.setInternalState(..)
來設置私有成員。
一種侵入性較小的方法是模擬getter方法。 這是否可行將取決於其他什么取決於內部狀態,但如果它足夠,它是更清潔的解決方案。
我過去使用的一些方法:
另一種選擇,如果你真的討厭公開,就是創建一個用於測試的子類,並在那里提供公共訪問。
你有幾個選擇:
有關一系列有用的技巧,請查看Michael Feather的書“有效地使用遺留代碼”
您可以為只讀變量添加帶參數的構造函數。 不要忘記添加默認(零參數)構造函數。
@Entity
class MyEntity
{
@Id
private Integer _ix;
public MyEntity(Integer ix) {
_ix = ix;
}
public MyEntity() {
/*
* Default constructor
*/
}
public Integer ixGet()
{
return this._ix;
}
}
構造函數是我認為最好的方法。 如果此實體必須非常只讀(根本不允許在生產代碼中創建新實例),則可以使用包訪問權限構建器,並僅在測試中使用它。 並且即使您將默認構造函數設為私有或具有包訪問權限,您的持久性提供程序仍然可以使用此類實體,但不確定 - 請查看eclipselink文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.