我希望能够模拟MyFunction
,但是当调用MyFunction
时我需要模拟返回不同的值。
是否可以根据功能的调用顺序使用with-redefs
返回不同的值?
(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)))))
答案 0 :(得分:5)
您可以使用可变的返回值集合,然后在每次调用时从中返回/删除值。
(defn foo [x] (inc x)) ;; example fn to be mocked
如果您要模拟对foo
的三个调用,分别返回1、2和3:
(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
使用swap-vals!
获取原子的旧值/新值,但需要Clojure 1.9或更高版本。
如果您没有swap-vals!
,则可以这样做(原子程度较低),如下所示:
(with-redefs [foo (let [results (atom [1 2 3])]
(fn [_]
(let [result (first @results)]
(swap! results rest)
result)))]
...)
答案 1 :(得分:1)
为此,我们使用Picomock,并为每个调用确定参数,并确定调用次数。推荐!