I am implementing a model in Java which requires iterating over a collection and going through a number of identification stages, it involves for loops, while loops etc. It is the sort of thing I want to test at a fine-grained level so that I have confidence it has been implemented properly.
I have used it as an opportunity to start unit testing, as it is something I recognise as being beneficial to my code. I have since been reading a forest of books to get up to speed with JUnit and unit testing.
Basically my question comes down to two conflicting pieces of advice I have received:
1) Statics are evil. Do not touch statics. Do not test privates either, you probably want a class there instead.
2) Use factories for creation to allow dependency injection using parameters – potentially allowing use of mocks and stubs for isolation.
In my example I am looking to perform an operation along the lines of:
double height = 223.42; // this was set iterating over a collection of doubles
//blah
HeightBounds b = HeightBounds.getHeightBounds(height);
//more blah
I have done this in order to avoid building up what would become a very long and complicated block of code, which I can only test in its entirety. This way I have public accessible objects that I can test to ensure the system components all perform correctly.
Common sense says to me there is nothing wrong with static factories, and that they are easily tested, but am I missing something blindingly obvious given I am learning test-driven design?
Thank you
The static factory class introduces coupling between your class and the
HeightBoundsclass. this might make your class difficult to test, if for exampleHeightBoundsgoes off and looks in DB for information, or reads from a web service etc etc.If you instead injected an
IHeightBoundsimplementation into your class then you could mock that out so you could test what happens when the dependencies of you class do certain things.For example what if
HeightBoundsthrows an exception? or returns null? Or you want to test when a particularHeightBoundis returned? With an interface it is easy to mock this behaviour, with a static factory it is more difficult as you have manufacture the data to create the desired results in the class.You could still only have a single implementation of
HeightBoundsand would be able to test that in isolation, but you would be able to test your method above without even having an real implementation.I would probably have an
IHeightBoundFactoryinterface and inject an implementation into the class.As for testing the privates, generally you don’t want to. You want to be testing one of 2 things, either that the results are what you expected or that the interactions are what you expected.
If you have a method called
Addand a method calledGetAllthen you might want to test that when you callAddand then callGetAllyou get back the one you added. you don’t care how this is implemented, just that it works. this is testing the results. Generally in this situation you want to create mock objects that return data. This seems to be your situation.If when you call
Addyou expect that what is being added is logged, then you want to test the interactions with the logging dependency, so you inject a mock dependency and verify that the interaction with that class happened when you calledAdd. Generally in this situation you want to create mock objects that have expectations set, and you verify that those expectations have been met. It doesn’t look this is necessary in the situation you described above.