28
votes

I want to mock a static final variable as well as mock a i18n class using JUnit, EasyMock or PowerMock. How do I do that?

2

2 Answers

49
votes

Is there something like mocking a variable? I would call that re-assign. I don't think EasyMock or PowerMock will give you an easy way to re-assign a static final field (it sounds like a strange use-case).

If you want to do that there probably is something wrong with your design: avoid static final (or more commonly global constants) if you know a variable may have another value, even for test purpose.

Anyways, you can achieve that using reflection (from: 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);
}

Use it as follows:

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

Don't forget to reset the field to its original value when tearing down.

5
votes

It can be done using a combination of PowerMock features. Static mocking using the @PrepareForTest({...}) annotation, mocking your field (I am using Mockito.mock(...), but you could use the equivalent EasyMock construct) and then setting your value using the WhiteBox.setInternalState(...) method. Note this will work even if your variable is private.

See this link for an extended example: http://codyaray.com/2012/05/mocking-static-java-util-logger-with-easymocks-powermock-extension