2012-03-14 11 views

risposta

36

C'è qualcosa come che simula una variabile? Lo chiamerei riassegnare. Non penso che EasyMock o PowerMock ti daranno un modo semplice per riassegnare un campo static final (sembra uno strano caso d'uso).

Se si vuole farlo, probabilmente c'è qualcosa di sbagliato nella progettazione: evitare static final (o più comunemente le costanti globali) se si sa che una variabile può avere un altro valore, anche a scopo di test.

In ogni modo, è possibile ottenere che l'uso di riflessione (da: Using reflection to change static final File.separatorChar for unit testing?):

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

usarlo come segue:

setFinalStatic(MyClass.class.getField("myField"), "newValue"); // For a String 

Non dimenticare di reimpostare il campo al suo valore originale quando abbattere.

+4

Chiunque usi questo dovrebbe tenere presente che il compilatore Java può incorporare costanti e quindi il codice potrebbe non accedere effettivamente ad altri campi finali (dovrebbe funzionare per File.separatorChar perché la costante sarebbe inutile quando inline). Questo è descritto in [questa domanda] (http://stackoverflow.com/questions/5173372/java-static-final-values-replaced-in-code-when-compiling) –

+0

Se so che la variabile ha solo un altro valore durante test unitario, quale sarebbe l'approccio suggerito? – Sharif

5

È possibile utilizzare una combinazione di funzionalità PowerMock. Statica che deride usando l'annotazione @PrepareForTest({...}), prendendo in giro il tuo campo (sto usando Mockito.mock(...), ma potresti usare il costrutto equivalente di EasyMock) e poi imposta il tuo valore usando il metodo WhiteBox.setInternalState(...). Nota questo funzionerà anche se la tua variabile è private.

Vedi questo link per un esempio esteso: http://codyaray.com/2012/05/mocking-static-java-util-logger-with-easymocks-powermock-extension

+1

Nota: il "collegamento per un esempio esteso" si riferisce alla simulazione di un campo ** statico **, non di un campo ** statico finale ** come indicato nella domanda. –

-1

https://github.com/zhangyanwei/staticmock

  1. StaticMockito.enhanceClass ("xxx.Utility");
  2. StaticMockito.initMock (Utility.class);
  3. quando (Utility.toClientId (clientName)). ThenReturn ("nome"); verify (mocker (Utility.class)). ToClientId (clientName);