2016-05-16 269 views
0

我有困難時間嘲笑類中私有靜態最終字符串字段。這裏是我的Java代碼示例:使用Mockito模擬私有靜態最終字符串

public class Fruit { 
private static final String FRUIT = "apple"; 

public void getFruit() { 
    System.out.println("I like " + FRUIT); 
} 

}

而且我用的Mockito嘲笑水果變量,這樣我可以從「蘋果」到「芒果」改變水果的價值。對於這裏是我的測試:

public class FruitTest { 
@Test 
public void testFruit() throws NoSuchFieldException, SecurityException, Exception { 
    setFinalStatic(Fruit.class.getDeclaredField("FRUIT"), "mango"); 
    Fruit fruit = new Fruit(); 
    fruit.getFruit(); 
} 

static void setFinalStatic(Field field, Object newValue) throws Exception { 
    field.setAccessible(true); 
    Field modifiersField = Field.class.getDeclaredField("modifiers"); 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
    field.set(null, newValue); 
} 

}

當我做System.out.println("I like " + FRUIT); 我期待它會打印芒果,但它仍然是印刷蘋果。我真的很感激,如果任何人都可以幫助我這個只有使用MOCKITO而不是PowerMock等

+2

'Fruit'類的行爲將總是返回'apple'。因此,我認爲你不應該改變這一點。如果你想要返回一個可變類型的水果,那麼不要將字段設置爲'static final',並使用'when()'來模擬你想要的行爲。 –

回答

0

編譯時常量可以由javac內聯進行優化。如果你改變你的水果類的東西類似於:

public static class Fruit { public static final String FRUIT = getFruit();

public static String getFruit() { 
     return "apple"; 
    } 



} 

它會顯示與 setFinalStatic結果芒果(Fruit.class.getField( 「水果」), 「芒果」); System.out.println(Fruit.FRUIT);

0

我最近調查了一些靜態字段,我不認爲你可以在沒有powermock的幫助下做你想做的事情。我也不確定你爲什麼想要。一個私有靜態final字段是一個常量,並且不應該有一個真正的原因,爲什麼你會想要一個常量改變。任何試圖這樣做的測試都是試圖測試錯誤的東西。

0

更改常量的值不是一個好習慣。更重要的是,我認爲這是不可能的。但是,如果您想更改字段的值,請刪除修飾符「final」。

0

單詞最終正好描述了一旦該字符串被創建後,您不應該更改該值。這是您在Java中獲取常量的方式。你的getFruit方法將總是返回「apple」。 Mockito不會幫助你。如果你正在測試這個方法,你需要測試它總是返回「蘋果」。在你的情況下,這個方法是靜態的還是沒有關係,因爲你要返回的是一個常數值。使用反思並不是一個好主意,不僅僅因爲它是一種非常糟糕的編程習慣,而且還因爲你沒有辦法在將來適當地管理變化。這是一種侵入式代碼,需要大量的維護,並且它總是會生成若干行,以便在運行時更改該方法以便「可以進行測試」。所有現實生活中的情況都不需要在單元測試中進行反思,除非有足夠的理由,或者僅僅是架構需要改進。反思更多的是學術性的東西,或者如果你正在建立自己的注射系統,嘲弄工具或任何需要這種編碼的東西。

相關問題