I would like to be able to mock MyFunction
however I need the mock to return different values when MyFunction
is called.
Is it possible to use with-redefs
to return different values based on the call order of a function?
(testing "POST /foo/bar and return ok"
(with-redefs [->Baz (fn [_]
(reify MyProtocol (MyFunction [_] [{:something 1}]))
(reify MyProtocol (MyFunction [_] [{:something 2}])))]
(let [response (routes/foo {:request-method :post
:uri "/foo/bar"
:query-params {}
})]
(is (= (:status response) 200)))))
You could use a mutable collection of the return values, then return/remove values from it on each call.
(defn foo [x] (inc x)) ;; example fn to be mocked
If you wanted to mock three calls to foo
returning 1, 2, and 3 respectively:
(with-redefs [foo (let [results (atom [1 2 3])]
(fn [_] (ffirst (swap-vals! results rest))))]
(prn (foo 0))
(prn (foo 0))
(prn (foo 0))
;; additional calls would return nil
(prn (foo 0)))
;; 1
;; 2
;; 3
;; nil
That uses swap-vals!
to get the old/new values of the atom, but requires Clojure 1.9 or greater.
If you don't have swap-vals!
you could do it (less atomically) like this:
(with-redefs [foo (let [results (atom [1 2 3])]
(fn [_]
(let [result (first @results)]
(swap! results rest)
result)))]
...)
We use Picomock for this, and to assert on the parameters for each call, and to assert on the number of calls. Recommended!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.