26

I would like to write unit tests for functions defined as private using defn-. How can I do this?

asked May 26, 2016 at 21:24

2 Answers 2

33

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))))))
answered May 26, 2016 at 21:31
4
  • 4
    Using 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. Commented May 26, 2016 at 21:41
  • @AlanThompson Huh, looks like clojure.lang.Var implements IFn. I didn't know that. I suppose it makes a certain amount of sense.... Commented May 26, 2016 at 22:38
  • kind of sad, private was patched up in clojure like that Commented Jul 5, 2017 at 19:18
  • 1
    You can use this to execute private functions in a nREPL, very useful to learn about a codebase you're not familiar with! Commented Feb 14, 2020 at 14:21
5

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:

  1. Require this file where you need the private functions, e.g. in your API definition with something like (:require [yourappname.utils :refer :all])
  2. 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.

answered Jan 14, 2019 at 11:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.