I would like to write unit tests for functions defined as private using defn-. How can I do this?
2 Answers 2
It turns out that you can use the reader macro #' or var to refer to the private function to be tested. If the private function is in namespace a.b and has the name c:
(ns a.b-test
(:use
[clojure test]))
(deftest a-private-function-test
(testing "a private function"
(let [fun #'a.b/c]
(is (not (fun nil))))))
-
4Using the syntax
#'a.b/d
is a shortcut for(var a.b/d)
, with returns the "var" which points to the "function"a.b/d
. When Clojure sees the var, it automatically substitutes the function before evaluation. I found this (mostly undocumented) behavior quite confusing for several years.Alan Thompson– Alan Thompson2016年05月26日 21:41:16 +00:00Commented May 26, 2016 at 21:41 -
@AlanThompson Huh, looks like
clojure.lang.Var
implementsIFn
. I didn't know that. I suppose it makes a certain amount of sense....Nathan Davis– Nathan Davis2016年05月26日 22:38:21 +00:00Commented May 26, 2016 at 22:38 -
kind of sad, private was patched up in clojure like thatmatanox– matanox2017年07月05日 19:18:31 +00:00Commented Jul 5, 2017 at 19:18
-
1You can use this to execute private functions in a nREPL, very useful to learn about a codebase you're not familiar with!UnsafePointer– UnsafePointer2020年02月14日 14:21:14 +00:00Commented Feb 14, 2020 at 14:21
Following the conversation on this topic here: https://groups.google.com/forum/#!msg/clojure/mJqplAdt3TY/GjcWuXQzPKcJ
I would recommend that you don't write private functions with defn-
but instead put your private functions in a separate namespace (and therefore clj
file, e.g. utils.clj
).
Then you:
- Require this file where you need the private functions, e.g. in your API definition with something like
(:require [yourappname.utils :refer :all])
- Require this file in your test namespace to test the functions.
Then, any user of your API won't see or have access to these helper functions, unless of course they require the utils file, which presumably means they know what they are doing.