thermostat

Just a TDD exercise
git clone https://git.tronto.net/thermostat
Download | Log | Files | Refs | README

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.