Testing private functions in Clojure

Something which has been bugging me for a while is that it's not possible to test private functions in Clojure. At least that's what I thought. There's a neat little trick you can use to work around this (which also demonstrates that private vars are still accessible if you try hard enough).

Any var, private or not, is accessible if you refer to it with a fully-qualified var name (using var or the #' reader macro).



(ns example)

(defn ^:private foo [x] (* x x))


(ns example-test
  (:require [clojure.test :refer :all]
            [example :refer :all]))

(deftest test-foo
  ;; This won't work because foo is private
  (is (= 4 (foo 2)))
  ;; Referring to the fully-qualified var *does* work.
  (is (= 4 (#'example/foo 2))))

While I think this is perfectly OK to use for tests, it's probably a very bad idea to use this in any other context. The other takeaway is that you can't depend on private vars actually being private. Everything is accessible if you refer to it directly.