Unit Testing and Refactoring Legacy Code

In this video I will be unit testing and do some refactoring of some piece of legacy code (existing code without unit tests). The code is based upon the "Tire Pressure Kata" as described in "The Coding Dojo Handbook" by Emily Bache.


The goal of this unit testing/refactoring move is to ultimately remove the hard dependency in the Alarm class. As you will see, Alarm depends on Sensor (because Sensor is instantiated in the Alarm class). It would be better if we could somehow inject the Sensor class into the Alarm class, instead of creating the Sensor class in the Alarm class itself.

When refactoring you preferrably do not want to touch the production code when there are no unit tests available. The only exception to this rule of thumb is automated refactorings done by your IDE (like extract methods etc.)

Description of the Tire pressure Kata

The Alarm class is designed to monitor tire pressure and set an alarm if the pressure falls outside of the expected range. The Sensor class provided for the excercise fakes the behaviour of a real tire sensor from a racing car, providing random but realistic values. Write the unit tests for the Alarm class.

Always test in production...
Don't be a wuss, always test in production!!!

First step : Unit Testing

First I covered the Alarm class with unit tests before the actual refactoring takes place. Only automated refactorings are done while testing. Sensor class is instantiated inside the Alarm class, so mocking the Sensor is out of the question. To work around this problem, I created a "seem" and used inheritance in my Alarm test class.

Second step : Refactoring

Next up was the actual refactoring move, injecting Sensor into the Alarm class. The last step was to get rid of the "AlarmShould" subclass (subclass of Alarm) by means of a Mock object. While refactoring I also tried to take care of the readabillity of the code.

Note that at the end of the refactoring session, the signature of the constructor has changed. Any other class that depends on Alarm must also be changed.