Дразнить существующие методы в 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 так велика.

Другие вопросы по тегам