Как я могу использовать with-redefs для насмешки нескольких вызовов одной и той же функции? - PullRequest
0 голосов
/ 29 октября 2018

Я хотел бы иметь возможность смоделировать 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)))))

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Мы используем Picomock для этого и для подтверждения параметров каждого вызова, а также для определения количества вызовов. Рекомендуется!

0 голосов
/ 29 октября 2018

Вы можете использовать изменяемую коллекцию возвращаемых значений, а затем возвращать / удалять значения из нее при каждом вызове.

(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)))]
  ...)
...