Having recently finished reading Clean Code by Robert C Martin I decided go back to my MoneyJar application for a little cleaning. Also, I have been re-reading Working Effectively with Legacy Code by Michael Feathers, so I figured it might also be a good idea to start covering the application with unit tests.
The learning experience has been exceptional. Mostly because much of the code I had written previously was very hard to follow, and needed a lot of work to make the logic clearer. But also, while adding unit tests, it highlighted how inadequate the system was for supporting unit tests. Trying to isolate the behaviours and dependencies have been a real head scratcher and it is clear that the support for testing would have been much easier when using test-driven development to begin with.
Although I am cheating somewhat. In Working with Legacy Code the idea is to nail down the behaviour before making any changes to ensure that you are not breaking anything. However, in my experience with this application it was easier to re-write some of the code first in order to support the tests using the smallest of changes (think of it as small incisions) in order to inject dependencies. Once that was set up, I was then able to inject mock objects using EasyMock and verifying method calls.
There have been some interesting results, as many of the classes were not written to support tests. One class had only one public method, no dependencies, and several private methods to help perform its duties. This class was extremely difficult to cover in tests as many of the private methods were inaccessible.
I have also found it very difficult to cover controller classes and view classes with unit tests. The problem I had with one of my controller classes was the shear number of dependencies it had, and that I had to eventually mock many dependencies to isolate and verify the behaviour of the class. It was so difficult I had to wonder if controller classes were inherently difficult to test.
At the moment I am using a code coverage tool to determine the amount of coverage I am getting for my application, however, it appears that only a mere third of the classes is under test, and that many of the outstanding lines of code to be covered by tests tend to be controller or view classes.
Anyway, it’s taking some time to get through, but I am very pleased with the results I am getting. Not only is my code getting cleaner, it was also getting more coverage by tests. The design of the program is also changing as a result to reduce the number of dependencies and overall complexity is being reduced.
However, during this period no new features are being added which is a little frustrating I would really like to start working at the persistence and data storage side of the application. Particular the database side of things including but probably not limited to – database design, MySQL, and JDBC.