Thermostat
This is an exercise for TDD. Check the git log to see the RED-GREEN-REFACTOR process.
Questions and comments
Question(s)
One of the points of the exercise is to find a way to “mock” the system time, so we can inject the dependency and test the program regardless of the current time. But I actually had to look up how to get the current time from the system in python. However, I had no way to properly test it if I were to follow the TDD workflow strictly.
How can I test that the system library to get the current time actually works, and that I am calling it correctly?
This is something I seriously would like to test in real life. After writing down this question I recalled reading about testing external libraries - maybe in Clean Code by Uncle Bob, or in one of his videos. He mentions writing learning tests to do just this, if I am not mistaken.
My follow-up question then is: what do I do with these learning tests? Do I keep them in production code, remove them before merging to master, or just throw them away as soon as I learn what I need?
Comment(s)
I do not quite like how I injected the dependency for the system
time. I think the reason is that this global state is hidden behind
some instance property in the Thermostat
class (i.e. the method
GetCurrentTime()
). Mocking this state requires fiddling with an
object’s internal state. I think this is something I dislike about
OOP in general.
After some reflection, I think a better way of mocking this state would something along these lines:
def GetCurrentRequiredTemperatureAtTime(self, time):
# logic for getting temp here
def GetCurrentRequiredTemperature(self):
time = int(datetime.now().strftime("%H"))
return self.GetCurrentRequiredTemperatureAtTime(time)
This also removes the need for the mocking class with its overrides.
I added this version in the thermostat-alt.py
file.
But then I asked myself: if I dislike how state is managed here and
prefer having an explicit parameter, why not also getting rid of
the whole state of the Thermostat
class and using something like
def GetCurrentRequiredTemperatureAtTimeWithState(time, state):
# logic here, current set points given in state
But then I answered myself that the OOP approach works better here.
We don’t care what the state
variable holds inside, so we might
just as well leave it at the Thermostat
class to manage it.
But for external dependencies, I think I like the explicit parameter version more.