免責聲明:很多狩獵後圍繞各個線程我發現一個答案。這是可以做到的,但一般的共識是,這是不是很安全,但看到你是如何做只在單元測試,我想你接受這些風險:)
答案是不是嘲笑,因爲大多數Mocking不允許你進入決賽。答案有點「哈克」,當Java調用時,實際上修改私有字段的核心是核心java.lang.reflect.Field
和java.lang.reflect.Modifier
類(反射)。看着this answer我能夠拼湊出剩下的測試,而不需要嘲笑解決你的問題。
該答案的問題是我試圖修改variable
時遇到NoSuchFieldException
。對此的幫助在於another post關於如何訪問私有而非公開的字段。
反射/域操作說明:
由於懲戒不能處理的最後,而不是我們最終做的是黑客進入該領域本身的根源。當我們使用Field
操作(反射)時,我們正在尋找類/對象內的特定變量。一旦Java找到它,我們就會得到它的「修飾符」,它告訴變量它有什麼限制/規則,像final
,static
,private
,public
等等。我們找到正確的變量,然後告訴代碼它可以被訪問允許我們改變這些修飾符。一旦我們改變了根的「訪問」以允許我們操縱它,我們就切換了它的「最終」部分。然後我們可以改變它的價值並將其設置爲我們需要的任何東西。簡而言之,我們正在修改變量以允許我們更改其屬性,刪除final
的價格,然後更改價值,因爲它不再是final
。欲瞭解更多信息,請致電check out the post where the idea came from。
那麼一步,我們在我們要處理的變量傳遞步驟和...
// Mark the field as public so we can toy with it
field.setAccessible(true);
// Get the Modifiers for the Fields
Field modifiersField = Field.class.getDeclaredField("modifiers");
// Allow us to change the modifiers
modifiersField.setAccessible(true);
// Remove final modifier from field by blanking out the bit that says "FINAL" in the Modifiers
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// Set new value
field.set(null, newValue);
結合這一切變成一個新的超級回答你。
@RunWith(PowerMockRunner.class)
@PrepareForTest()
class PrivateStaticFinalTest {
@Test
public void testMethod(){
try {
setFinalStatic(PrivateStaticFinal.class.getDeclaredField("variable"), Integer.valueOf(100));
}
catch (SecurityException e) {fail();}
catch (NoSuchFieldException e) {fail();}
catch (Exception e) {fail();}
assertEquals(PrivateStaticFinal.method(), Integer.valueOf(101));
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
更新 上述解決方案將只工作了這是在靜態初始化block.When聲明,並在同一時間初始化常數這些常數,它可以發生,編譯器內聯的,在這一點任何對原始值的改變都會被忽略。
這些靜態都在同一類,這使得它很棘手。我遇到的所有問題都是在嘗試測試課程時使用來自其他地方的靜態信息。不得不嘲笑你想要測試的類的部分部分似乎很糟糕。你永遠不應該嘲笑你正在測試的類,只是它依賴的東西。 – Walls