Showing posts with label Midje. Show all posts
Showing posts with label Midje. Show all posts

Monday, August 15, 2016

Kata: Bank Account in Clojure using outside-in TDD with Component and Midje

I did the Printing Account Statement subset of the Bank Account kata in Clojure using Component and Midje.

I started the kata in a Barcelona Clojure Developers event.

The truth is that, since I was learning how to use the Component library, I didn't use TDD.

Instead I worked on the REPL to get everything in place and make it work.

Then I wrote the tests I would have liked to write if I had used outside-in TDD with Midje.

I find that, when I'm learning something new, it works better for me what Brian Marick describes in these tweets: Now I'll show you the tests I actually wrote afterwards, in the order I would have written them doing outside-in TDD.

This is the acceptance test I would have started with:

Then I would have written this unit test for Account:

And these are the ones for InMemoryTransactions, ConsoleStatementPrinter and NiceReverseStatementFormat:

You can check the rest of the tests and code in this GitHub repository.

Doing this kata I learned and practiced how to use Component.

I also learned how to use Midje's defrecord-openly and provided macros to mock protocols which helped me correct something I did wrong in another kata.

Thursday, July 28, 2016

Revisited Kata: Using Midje's defrecord-openly to mock a protocol in Ohce

Several weeks ago I did the Ohce kata in Clojure using outside-in TDD with Midje (as I explained in a previous post).

In that post I said that I hadn't used Midje's defrecord-openly and provided macros and had instead decided to write my own code to capture the arguments with which the functions of the Notifier protocol implementation were being called because:
... I didn't like having to use defrecord-openly in production code.
Well, I was wrong!

It turns out that it is not necessary at all to use defrecord-openly in your production code in order to mock a protocol.

I understood it thanks to this answer in Stak Overflow: Mocking Clojure protocols.

The only thing I needed to do was to use defrecord-openly to create a fake implementation of the Notifier protocol inside the test code like this:

and then write the tests against this unimplemented fake.

This are the new Ohce tests:

As you can see it's very easy to use Midje's defrecord-openly to mock protocols.

I just misunderstood Midje's documentation the first time I tried to do it...

Wednesday, July 13, 2016

An example of using dynamic fact descriptions in Midje

I had these tests written in Midje which had some duplication:

but were providing a nice level of feedback when there was an error:

In my first attempt to remove the duplication in the facts:

I lost the level of feedback the original tests had. It didn't tell which sorter was failing:

By using dynamic fact descriptions (notice the use of the :midje/description metada):

I was able to keep the original level of feedback and still remove the duplication:

Saturday, July 9, 2016

Kata: Ohce in Clojure using outside-in TDD with Midje

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.

Monday, August 25, 2014

Thursday, April 17, 2014

Interesting KataCast: "Clojure TDD demo (Robozzle)"

I've just watched this great explained katacast by Brian Marick

The top-down style Marick uses to grow his code through TDD reminds me a lot of how Gregor Kiczales worked through the example programs in Racket of his Introduction to Systematic Program Design - Part 1 Coursera course that I took a while ago.

The difference between the two processes is basically in the tooling, because Midje allows Marick to "stub" the results of helper functions so he can get feedback about his top functions from the very beginning whereas in Kiczales' examples he had to wait until all the helpers were working to see the top functions tests pass.

Apart from that they use the same top-down approach.