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?
-
Possible duplicate of [Mock private static final field using mockito or Jmockit](http://stackoverflow.com/questions/30703149/mock-private-static-final-field-using-mockito-or-jmockit) – kecso Mar 14 '17 at 00:04
2 Answers
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.
-
4Anybody using this should keep in mind that the java compiler can inline constants and thus the code may not actually access other final fields (should work for File.separatorChar because the constant would be useless when inlined). This is described in [this question](http://stackoverflow.com/questions/5173372/java-static-final-values-replaced-in-code-when-compiling) – Markus Kreusch Apr 14 '14 at 21:53
-
1If i know the variable only have another value during unit testing, what would be the suggested approach? – Sharif Nov 02 '14 at 08:37
-
4This solution will not work with latest JDK-11 or higher. As modifying the value of a final variable has been discouraged in the vanilla version of JDK-11 or +. – Rohit Gaikwad Sep 20 '19 at 15:13
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

- 4,185
- 5
- 43
- 53
-
1Note - the "link for an extended example" refers to mocking a **static** field, not a **static final** field as mentioned in the question. – James Hargreaves Aug 10 '16 at 09:02