5

If a private static final value X from a class is needed in a unit test (in a separate package), how should one go about obtaining X? I can think of three options, none of which seems clean to me:

1) Copy X into the test class. I fear that if the source's X is changed, while the test's X is preserved, the unit test would still pass when it should fail.

2) Make X public. I fear this breaks encapsulation. Nonetheless, this is in my opinion the best option given that X is final.

3) Create a public getter for X. This also seems like it's breaking encapsulation if X should only be accessed from the class and unit test.

Master_Yoda
  • 1,092
  • 2
  • 10
  • 18
  • I think there's no general answer to this. One very important question: Is X mutable? If so, DON'T expose it for testing purposes. Maybe you can give a concrete example of your situation (with code) for discussion? – Ray Jun 27 '14 at 16:02
  • Another option would be to expose a package-visible (default visibility) getter. And since your test class would most like be defined in the same package, it won't break encapsulation *that much*. – Santa Jun 27 '14 at 16:04
  • The best way to deal with this is to write a test that defines the *behavior* you want to test, not some implementation detail value inside the object being tested. It's hard to be more helpful than that without example code. – tallseth Jun 27 '14 at 16:10
  • You could use default scope and place the test in the same package structure. But @tallseth is absolutely right about testing behavior. – Hannes Jun 27 '14 at 16:13
  • This link might help you: http://howtodoinjava.com/2012/11/05/unit-testing-best-practices-junit-reference-guide/ This link states best practices for Unit testing. It has one statement as "Do not use static members in a test class". – Mandar Pandit Jun 27 '14 at 16:15
  • This essentially the same as http://stackoverflow.com/questions/34571/whats-the-proper-way-to-test-a-class-with-private-methods-using-junit – Raedwald Jun 27 '14 at 19:52

3 Answers3

8

I would say you don't need to access it. If something is private, then it's used as an implementation detail and should be invisible to the test. You should test the requirements of the class, not the implementation details. Why you ask? Because, over time, the implantation is likely to change (or evolve) while the requirements should be consistent.

Isaiah van der Elst
  • 1,435
  • 9
  • 14
1

I would go with the third option of yours.

I would create a private static final variable in the test class and assign it with the getter, that gets the value of the private static final value required. This way your value at the test class would have the similar properties as the original values.

I hope this helps.

Lohit
  • 23
  • 8
0

You can always access your private methods and fields via reflection.

Field X = MyClass.class.Getdeclaredfield("X");

Then as your field is static you can get its value with one of the getXX methods of Field class on null. Ex :

Object o = X.get(null);
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • 3
    One problem to worry about when using reflection is the field names you are getting are Strings. So if you later ever rename the field or move it somewhere else, the code will still compile but will fail at Runtime – dkatzel Jun 27 '14 at 17:22