I should start by saying I'm new to Clojure, and FP in general. I've been reading the documentation about how to define prerequisites in Midje, but I can't make sense of some of it.
My understanding was that to do top-down TDD, you're supposed to start by writing a test in your test module, with an unfinished
statement at the top that 'declares' all the prerequisite functions you haven't defined yet. Then you can fiddle with those prerequisite functions in the provided
function within your test (describing their return values and such).
My confusion lies in how you're supposed to get your actual source module to recognize the prerequisite functions. Here's a very simple and contrived example I'll use to illustrate my meaning:
;;; in my run_game_test module
(ns clojure-ttt.run-game-test
(:require [midje.sweet :refer :all]
[clojure-ttt.run-game :refer [start-game]]))
(unfinished do-turns)
(fact "`start-game` returns whatever `do-turns` returns"
(start-game) => ..winner..
(provided
(do-turns) => ..winner..))
And then to make the test fail properly, I just write a stub of a function in my run_game
module.
(ns clojure-ttt.run-game)
(defn start-game
[])
So far so good. I run the tests and they fail because:
a) do-turns
isn't getting called
b) start-game
isn't returning anything.
So now to make the test pass, by changing start-game
to call and return (do-turns)
. For the record, do-turns
is a hypothetical prerequisite function that I'm going to get from a not-yet-existing module--which, as I understand, is how top-down TDD works.
(defn start-game
[]
(do-turns))
Now, understandably, I get a huge error; Clojure can't resolve the symbol do-turns
. So I thought, maybe if I (declare do-turns)
at the top I could keep it from blowing up. No, I get a different error because I'm trying to call an unbound function.
I tried a couple other ways of getting Clojure to recognize do-turns
but it seems like the unfinished
statement is giving it issues. Am I just using unfinished
wrong?
From the Midje docs:
So when you do
(unfinished do-turns)
and then call it with(do-turns)
an exception is thrown:You can fix this by removing the
(unfinished do-turns)
part and provide an implementation ofdo-turns
. E.g.,and refer it in your test
Note that when you have provided an implementation of
do-turns
,(unfinished do-turns)
will throw an exception since an implementation already exists, so it is removed.Now you have shown that a call to
(start-game)
returns what(do-turns
) returns.