web-dev-qa-db-fra.com

Comment simuler une variable finale statique à l'aide de JUnit, EasyMock ou PowerMock

Je veux simuler une variable finale statique ainsi que simuler une classe i18n en utilisant JUnit, EasyMock ou PowerMock. Comment je fais ça?

23
Prince

Existe-t-il quelque chose comme se moquant d'une variable? J'appellerais cela une réaffectation. Je ne pense pas qu'EasyMock ou PowerMock vous donneront un moyen facile de réaffecter un static final champ (cela ressemble à un cas d'utilisation étrange).

Si vous voulez le faire, il y a probablement un problème avec votre conception: évitez static final (ou plus généralement des constantes globales) si vous savez qu'une variable peut avoir une autre valeur, même à des fins de test.

Quoi qu'il en soit, vous pouvez y parvenir en utilisant la réflexion (à partir de: tilisation de la réflexion pour modifier le fichier File.separatorChar final statique pour les tests unitaires? ):

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

Utilisez-le comme suit:

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

N'oubliez pas de réinitialiser le champ à sa valeur d'origine lors de la suppression.

41
Antoine

Cela peut être fait en utilisant une combinaison de fonctionnalités PowerMock. Mocking statique à l'aide de l'annotation @PrepareForTest({...}), se moquant de votre champ (j'utilise Mockito.mock(...), mais vous pouvez utiliser la construction EasyMock équivalente), puis définissez votre valeur à l'aide de WhiteBox.setInternalState(...) méthode. Notez que cela fonctionnera même si votre variable est private.

Voir ce lien pour un exemple étendu: http://codyaray.com/2012/05/mocking-static-Java-util-logger-with-easymocks-powermock-extension

5
cwash