在 Clojure 中模拟现有方法
Posted
技术标签:
【中文标题】在 Clojure 中模拟现有方法【英文标题】:Mocking existing methods in Clojure 【发布时间】:2014-03-11 10:58:16 【问题描述】:我正在尝试使用with-redefs
和reify
来模拟clojure 中的方法。我不知道从哪里开始使用这些。谁能给我一个模拟方法的例子吗?互联网上的文档对我没有帮助,因为我现在完全混淆了。
【问题讨论】:
您是要模拟一个类的方法,还是模拟一个 clojure 函数(用 def 或 defn 定义) @Arthur Ulfeldt :我希望模拟两者 您可能会发现有用的github.com/asyntactic/dynamic-reify 以及函数和变量的基本示例gist.github.com/jaimeagudo/8980813 【参考方案1】:假设您想监视/模拟/存根函数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 的表现力真是太棒了。
【讨论】:
【参考方案2】:“The Joy of Clojure (Manning)”一书可能是一个很好的起点,“13.2 测试”部分提供了一些关于(以及其他)您提到的技术的信息 - 使用 with-redefs
宏。
【讨论】:
这是本书的第一版。如果您使用的是“The Joy of Clojure”的第 2 版,这已移至第 17.2 节以上是关于在 Clojure 中模拟现有方法的主要内容,如果未能解决你的问题,请参考以下文章