user193116
user193116

Reputation: 3568

In clojure test, how to mock out multiple methods when testing one function?

I am writing a clojure.test unit test for a rather large function in my application. This function makes several calls to db and external REST services and does some computation. for example, my function to be tested is like so

(defn myfunc [id]
   (let[
        w (some-security-call id)
        x (some-db-call id)
        y  (some-REST-call x)
        z ( some-audit-call y)

       ]
       (-> y :somekey )))

for the purpose of testing this method, I want to stub out or redefine "some-audit-call" and "some-security-call". Clojure's with-redefs-fn only redefines one method at one time.

Is there a standad way to mock out multiple functions used in a function being unit tested?

Upvotes: 0

Views: 1738

Answers (1)

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91617

with-redefs works on as many functions as you want. Here is a redacted example from my actual production tests.

(with-redefs [namespace/redacted            (constantly [])
              namespace/redacted                 (fn [& args] (async/go namespace/redacted))
              namespace/redacted        (constantly [2 4])
              namespace/redacted                (fn [& args] (namespace/redacted sample-redacted-ads))
              namespace/redacted                (fn [_ _ redacted & _]
                                                  (async/go (cond-> namespace/redacted
                                                              namespace/redacted (dissoc redacted))))
              namespace/redacted                   (fn [& args] (async/go nil))
              namespace/redacted       fake-redacted
              namespace/redacted       fake-redacted
              namespace/redacted      namespace/redacted
              namespace/redacted       (go (constantly []))
              namespace/redacted               (fn [_] [])
              namespace/redacted      namespace/redacted
              namespace/redacted      namespace/redacted
              namespace/redacted                        (fn [_] {:redacted "redacted"})]
  (is (= "redacted"
         (get-in (<!!
                  )
                 ))
      "We should return the redacted if we don't pass it in")
  ... many more tests here ...

)

if you need to redefine a function that is used by another function that you want to redefine then you have to nest the calls to with-redef. this sometimes causes people to think that with-redefs only works with one function.

You likely don't want to use with-redefs-fn unless you know you have a specific reason.

Upvotes: 1

Related Questions