0

I'm using the following snippet from this answer .

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

Here's a part of my MyClassTest that calls the above method.(pathToFile is a private static final field in MyClass).

public static void main (String ... args) {
        try{
            setFinalStatic(MyClass.class.getDeclaredField("pathtoFile"), "test-propFile.properties");
            System.out.println(MyClass.class.getDeclaredField("pathtoFile"));// prints the original value of pathToFile.
// how do I access the  modified value  pathToFile here?
        }
        catch(Exception e){
            e.printStackTrace();

        }

Also, is doing this, the right approach to unit testing a private static final field? Any comments/suggestions/links appreciated.

Community
  • 1
  • 1
seeker
  • 6,841
  • 24
  • 64
  • 100
  • I presume the `MyClass` vs `LMSValidation` mismatch is a typo? – Ian Roberts Feb 11 '15 at 18:57
  • "*is doing this, the right approach to unit testing a private static final field?*" does it work? Do you have any problems with it? – Pshemo Feb 11 '15 at 18:58
  • `private static final` usually mean internal constant, what are you trying to test here? –  Feb 11 '15 at 19:52
  • I have a properties file pointed to by that variable. Im trying to point to a test property file for purposes of testing. Is there a better approach to this? – seeker Feb 11 '15 at 20:05
  • @Pshemo: refer comment in second code block . *How do I access the modified value to the private variable* – seeker Feb 11 '15 at 20:06
  • "*How do I access the modified value to the private variable*" you are accessing it same way you accessed other private values, using `setAccessible(true)` just like you did in `setFinalStatic` method with `modifiers` field. Then you can simply invoke `yourPrivateField.get(null)`. But if this value will be changed or not depends if it was simple constant (created at runtime), or compile-time constant like (known at compilation time, like `static final String = "foo";`). Value of compile-time constants are indiled, so changing them will not affect already compiled code which uses them. – Pshemo Feb 12 '15 at 12:44
  • You should probably read question related to the one you pointed in your post: http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection. Also maybe my earlier comment under accepted answer in that question will be helpful http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection#comment30350617_3301720 – Pshemo Feb 12 '15 at 12:46

1 Answers1

1

you don't test constants. you use them and test the code that uses them.

static final double pi = 3.14...
let calculate_circuit r = 2 pi r

why would you want to change the definition of pi?

if you need to test code with different value that means it's not a constant but configuration. then you have to refactor your code to decouple configuration and the code that uses it:

mail.server = mail.myCompany.com
send_email(String mailServer) = ....

and then you can easily test send_email using different mail servers

you probably can use reflection or higher-level tools like power mock but it's not really convenient and may indicate problems in future because of tight coupling

Titulum
  • 9,928
  • 11
  • 41
  • 79
piotrek
  • 13,982
  • 13
  • 79
  • 165