Дразнить существующие методы в Clojure
Я пытаюсь использовать with-redefs
а также reify
издеваться над методами в clojure. Я понятия не имею, с чего начать. Может кто-нибудь дать мне пример издевательства над методом? Документация в интернете мне не поможет, так как я полностью запутался в этом моменте.
2 ответа
Книга "Радость Clojure (Мэннинг)" может быть хорошей отправной точкой, раздел "13.2 Тестирование" содержит некоторую информацию относительно (среди прочего) техники, которую вы упомянули - использование with-redefs
макро.
Допустим, вы хотите шпионить / издеваться / заглушить функцию bar
и проверить, сколько раз он был вызван в функции foo
, Простой пример может быть:
(defn bar [] ...)
(defn foo []
(bar)
(bar)
(bar))
(deftest
(let [args (atom [])]
(with-redefs [bar (fn [x] (swap! args conj x))]
(foo)
(is (= (count @args) 3)))))
Ну, я согласен, что приведенный выше код немного утомителен. Вы можете попробовать следующий макрос: (я помещаю историю вызовов в метаданные)
(defmacro with-mock [vr & body]
`(with-redefs [~vr (with-meta
(fn [& ~'args] (swap! (-> ~vr meta :args) conj ~'args))
{:args (atom [])})]
(do ~@body)))
использование:
(with-mock bar
(foo)
(is (= (-> bar meta :args deref count)
3)))
С небольшим количеством утилит, макрос выше может стать мощным инструментом. Выразительность Clojure так велика.