2016-05-16 7 views
0

Ich habe eine Schwierigkeit Zeit verspotten ein privates statische letzte String-Feld in einer Klasse. Hier ist mein Java-Beispielcode:Mock private statische final String mit Mockito

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

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

}

Und ich verwenden Mockito die FRUIT Variable zu verspotten, so dass ich den Wert der FRUIT von "apple" ändern zu "Mango". Denn das hier ist mein Test:

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); 
} 

}

ich erwartet hatte, als ich System.out.println("I like " + FRUIT); tun es Mango drucken, aber noch ist es Apfeldruck. Ich würde wirklich schätzen, wenn jemand mir mit diesem ONLY USING MOCKITO und nicht PowerMock usw. helfen kann.

+2

Das Verhalten der 'Fruit' Klasse wird sein, immer' apple' zurückzugeben. Deshalb denke ich nicht, dass Sie das ändern sollten. Wenn Sie die Möglichkeit haben möchten, eine variable Fruchtart zurückzugeben, dann machen Sie nicht das Feld 'static final' und verwenden Sie' when() ', um das gewünschte Verhalten nachzuahmen. –

Antwort

0

Kompilierzeitkonstanten können von javac für Optimierung inlined sein. Wenn Sie Ihre Fruchtklasse etwas wie ändern:

öffentliche statische Klasse Fruit { öffentliche statische letzte Zeichenfolge FRUIT = getFruit();

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



} 

Es zeigt das Ergebnis Mango mit setFinalStatic (Fruit.class.getField ("FRUIT"), "Mango"); System.out.println (Frucht.FRUIT);

0

Ich habe mich in letzter Zeit über einige statische Felder lustig gemacht und ich glaube nicht, dass Sie das tun können, was Sie versuchen, ohne die Hilfe von powermock. Ich bin mir auch nicht sicher, warum du das willst. Ein privates statisches Endfeld ist eine Konstante, und es sollte keinen wirklichen Grund geben, warum eine Konstante geändert werden sollte. Jeder Test versucht, das Falsche zu testen.

0

Es ist keine gute Methode, den Wert einer Konstanten zu ändern. Was es mehr ist, denke ich ist nicht möglich. Wenn Sie jedoch den Wert eines Feldes ändern möchten, entfernen Sie den Modifikator `final.

0

Das Wort final beschreibt genau, dass Sie diesen Wert nicht ändern sollen, sobald der String erstellt wurde. Auf diese Weise erhalten Sie Konstanten in Java. Ihre getFruit-Methode gibt immer "apple" zurück. Mockito wird dir dabei nicht helfen. Wenn Sie diese Methode testen, müssen Sie testen, dass sie immer "Apfel" zurückgibt. Und in Ihrem Fall ist es egal, ob die Methode statisch ist oder nicht, da das, was Sie zurückgeben, ein konstanter Wert ist. Die Verwendung von Reflektion ist keine gute Idee, nicht nur weil es eine wirklich schlechte Programmierpraxis ist, sondern auch, weil Sie keine Möglichkeit haben, Änderungen in der Zukunft richtig zu verwalten. Es ist solch ein invasiver Code, der eine enorme Menge an Wartung erfordert und immer mehrere Zeilen generiert, nur um diese Methode während der Laufzeit zu ändern, damit sie "getestet" werden kann. Alles in allem müssen reale Fälle nicht in Komponententests reflektiert werden, es sei denn, es gibt einen starken Grund dafür oder nur, dass die Architektur verbessert werden muss. Reflexion ist mehr eine akademische Sache oder wenn Sie Ihr eigenes Injektionssystem, ein spöttisches Werkzeug oder irgendetwas, das diese Art von Codierung erfordert, bauen.