I did
the Ohce kata in Clojure using outside-in TDD with
Midje.
I started by writing a nearly
end-to-end test for the scenario of running
ohce during the morning:
In this test I used
Midje's unfinished and provided macros to stub the
hour-fn and
read-input functions and
with-out-str to capture the any printed lines.
Using
Midje's future-facts macro I avoided seeing this acceptance test failing every time the tests were run, instead I saw a reminder message like this one:
Next I started testing
ohce at the unit level. These are the resulting facts:
For these facts I used a fake implementation of the
Notifier protocol:
which captured the arguments with which the functions of the protocol implementation were being called:
I could have used
Midje's defrecord-openly and provided macros instead but I didn't like having to use
defrecord-openly in production code.
Update:
The statement above is wrong. It is not necessary at all to use
defrecord-openly in your production code in order to mock a protocol. See how it's done in this other post:
Revisited Kata: Using Midje's defrecord-openly to mock a protocol in Ohce.
--------------------------
Another thing to notice in that test is the use of
Midje's metaconstants to avoid the facts knowing about the "shape" of data (where it was possible to do it).
Well, those facts lead to the following code:
Then I started applying TDD on the next level to write
ConsoleNotifier, an implementation of the
Notifier protocol:
and the
select-greeting function (
select-by-day-period in this case):
Once those tests were passing, I just had to inject a
ConsoleNotifier record and the
select-greeting function into
ohce to make the acceptance test pass:
I also added two other scenarios (running
ohce during the afternoon and during the night).
A curious thing to notice is that I couldn't use
partial with
select-greeting if I wanted the
provided macro to work with
hour-fn, that's why I used a lambda instead. Due to the same problem I also had to wrap the
read-input function inside a lambda.
Then to be able to really run
ohce on the console I just had to write a real
hour-fn function (tested on the REPL):
and create a -main function (read-input is just the Clojure's
read-line function):
This is an example of running
ohce:
I committed after each passing test and each tiny refactoring, so that you can follow the process if you feel like.
You can check the
commits step by step here.
You can find the resulting code in this
GitHub repository.
Doing this kata helped me to learn a lot of new things about Midje.