Clojure - Stubbing Multimethod

One way to achieve polymorpism in Clojure is to use multimethods.

With my TicTacToe application in Clojure, I have two different types of players, Human and Computer.

To do the polymorphic dispatch, I have a dispatch method which picks out the player_type value from the hash-map that is passed into it. For e.g, if I pass in {:player_type :human}, it’ll look for the multimethod which has :human label.

(defmulti get-move (fn [player-types board]
                         (player-types :player_type)))

In order to call the method, you’d do something like this;

player/get-move {:player_type :human} board

This will eventually delegate the method call to the following;

(defmethod player/get-move :human [_ board]
  (get-move-logic-goes-here board))

I think this is really nice.

Elsewhere, I have a play-game function that runs through the entire game and keeps track of the current player.

However, I don’t want to use my human-player code, nor do I want to use my computer-player code. I want to use a stub player instead, so I can control what the next move will be placed.

In my unit test, I declare a new method that my multimethod can dispatch to;

(defn prepare-stub-player-move [next-move]
  (defmethod player/get-move :stub-player [_ board] next-move))

In order to use a stub player, firstly I pass in a player to my play-turn function with the player_type stub-player.

In the unit test, prior to calling play-turn, I just call (prepare-stub-player-move some-move) to get the stub player to always return some-move.

There we have it, stubbed multimethods in Clojure.