Testing for Random
I have my easy function made, and honestly figuring out a test to write for it was harder than writing the code. (This seems to be a recurring theme with me and Test Driven Development).
The function is 3 lines of code, and one of those lines is just for readability.
(defn update-board-easy [board]
(let [available-moves (core/get-available-moves board)]
(core/update-board (rand-nth available-moves) board)))
core/get-available-moves
takes a board (sequence of numbers and either string “X” or “O”) and filters out anything
that is not a number.
I wrote a detailed post about
rand-nth
yesterday in case you missed it.
This was all easy to write… Most of it was already written by me weeks ago! The part I had to reach out for help on
was how to test for random. My mentor Alex gave me a nice shift in perspective when I asked about it. Testing for random
isn’t what we’re really trying to do here. We know that rand-nth works, it’s an official clojure.core function. What we
need to test is that our function is working as intended. In order to accomplish this, I needed the random number to be
something consistent in my tests. I managed to get this done with the with-redefs
function.
(it "returns a random valid move on empty board"
(with-redefs [rand-nth (stub :rand-nth {:return 0})]
(should= ["X" 1 2 3 4 5 6 7 8] (sut/update-board-easy (range 9)))))
with-redefs
lets us redefine a function inside a function. Its syntax is similar to let
. First word in the bracket
is the binding, the second is what you want to change. In our case above we used stub
to make the return of rand-nth
to consistently be 0.
Now that we have consistent outputs, we have consistent tests!