Thoppan / powermock

Automatically exported from code.google.com/p/powermock
Apache License 2.0
0 stars 0 forks source link

Whitebox.setInternalState doesn't work on a constant in an interface #324

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.Create an interface with a static final variable.
2.Create a test which calls Whitebox.setInternaState on the variable of the 
interface (also use @PrepareForTest for the interface).

What is the expected output? What do you see instead?
The value of the variable should be the value specified in the setInternalState 
statement.
But I get an exception:
java.lang.RuntimeException: Internal error: Failed to set field in method 
setInternalState. (full trace: see attachment)

What version of the product are you using? On what operating system?
powermock 1.4.6

Original issue reported on code.google.com by Nicolas....@t-online.de on 18 Apr 2011 at 5:36

Attachments:

GoogleCodeExporter commented 9 years ago
I forgot to mention that it works if I turn MyInterface into a class.

Original comment by Nicolas....@t-online.de on 18 Apr 2011 at 5:40

GoogleCodeExporter commented 9 years ago
Yup removal of final for static final fields on happens for classes. We can try 
to implement this for interfaces as well.

Original comment by johan.ha...@gmail.com on 18 Apr 2011 at 7:46

GoogleCodeExporter commented 9 years ago
I ran into a similar problem today:

this seems to fix the problem for me:

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

The problem with PowerMock is that it doesn't get rid of the final modifier 
that I could tell anyway.

I think this is what PowerMock need to do:
      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

I did find however that in my case I couldn't change a private static final 
int, I had to change it to an Integer.

Taken from:
http://stackoverflow.com/questions/3301635/change-private-static-final-field-usi
ng-java-reflection

Original comment by japear...@agiledigital.com.au on 9 May 2012 at 3:51

GoogleCodeExporter commented 9 years ago
I just ran into this issue for a class that contains a final attribute.  So 
this seems to be an issue with not just interfaces.  This is with Java 7, which 
may be a factor though.

Original comment by oliverhe...@gmail.com on 8 Feb 2013 at 7:31

GoogleCodeExporter commented 9 years ago
I also can confirm that WhiteBox.setInternalState does not work with class with 
a final field.

Original comment by kozakcs...@gmail.com on 29 Jul 2014 at 9:27