Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding 'Getters' and 'Setters' for the sake of unit testing?

I am currently working with some pretty iffy code. The code itself is not legacy, but the framework it uses is legacy and is pretty bad.

I want to start writing some junit tests for a class (for a change!) but in order to do so effectively I would need to add some getters and setters.

I need the setters so I can check the state of the private variables in the class (a kind of state machine design pattern going on here) and I need the getters to mock what the private variables in some methods are.

Would you guys say its bad, good or simply acceptable to add getters and setters to a class for the sake of being able to write unit tests?

like image 579
DeaIss Avatar asked Mar 28 '14 20:03

DeaIss


3 Answers

Adding code to production code solely for unit tests is something which I try to avoid.

An alternative for your case would be to retrieve the values via reflection, as it is possible to access even private members.

Field field = object.getClass().getDeclaredField("member");
field.setAccessible(true);
Object value = field.get(object);
like image 37
Steven Pessall Avatar answered Sep 25 '22 17:09

Steven Pessall


I prefer having all dependencies passed into the constructor, but assuming that would be too difficult to add to your existing system, just ensure the getters and setters are package private and clearly label them (annotation or javadoc) that they are visible purely for testing. Even better if you could add some static analysis tools to ensure the getters and setters are not called from production code only from test.

like image 41
Matthew Madson Avatar answered Sep 23 '22 17:09

Matthew Madson


I would avoid it. Generally speaking, you should structure things as best you can to avoid needing to test private variables and stick with the interactions that the rest of the application will be exposed to. This is typically public methods/properties and protected methods by using fakes/doubles.

The purpose of the unit tests are to verify how the object under test is interacted with, not necessarily it's implementation details. Basically, with input x, I should get output/effect y. If you get hung up on testing exactly how x produces y, you run the risk of making your classes inflexible to change. Every refactor of your class is likely to break your tests, even if the output and end result is the same.

like image 159
Brad Gardner Avatar answered Sep 22 '22 17:09

Brad Gardner