Question

To give some background I've been learning java for about 10 months now so I am really not that experienced. I have been reading a bit recently on how how its bad practice to test private methods and variables.

In the perfect world you shouldn't do this as it suggests bad design - however, I am working with a legacy framework where most methods are called via reflection and it IS bad design, but I cannot change that no matter what. Please don't reply saying "you should redesign your code" as I cannot change the way the framework works.

I want to test that a 'flow' class behaves in a certain way and calls the right methods depending on the state of private variables, and I want to make sure that certain methods set private instance variables to a correct value if another private variable has a certain value. This is so when I make future changes to the class I can ensure that the flow/behavior of the class hasn't broken or changed.

Now, because the flow is based largely on the state of private instance variables and because its bad to test the state of private instance variables - how else do I test the class?

Ways of testing the private variables that all work:

  1. Implement default access getters and setters at the end of the code and put the junit test class in same package. Comment these clearly that they should be used for testing only.

  2. Make instance variables default access instead of private and put junit test class in same package. No other classes in the same package will instantiate this class anyway.

  3. Test the private variables via reflection - I lose IDE functionality here as Eclipse won't refactor if I change the name of variables and could be a future pain of manually changing Strings to match variable names in the class to be tested.

Which of the three above is the "lesser" evil to use? Is it better to test private variables then have no tests at all?

Was it helpful?

Solution

The state of private fields is irrelevant to the correct functioning of the class. You shouldn't be testing private variables.

Test what the class does, not how it does it.

If you want to test that the class sets its internal state correctly, so it behaves in a particular way after that, then call the methods that set the state and test that the behaviour after that is correct.

It doesn't matter if it takes 1000's of tests to ensure that - they are only unit tests, so they'll be fast.

Future coders are at liberty to change the internal workings of a class, as long as the class' contract is upheld.

OTHER TIPS

The first option would be a good choice for you. While following a good coding practice, we should always make variables as private and methods to be public, so that variables can not be modified and methods can be accessed by outer world.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top