是否有任何方法使用类似于“提供”的语法来模拟(而不是存根)使用Midje (clojure)的协议函数?
这是问题的一部分:模拟屏蔽协议,但与嘲弄有关。
更详细的是:我有一个协议和一个函数来返回实现它的东西。我想对函数进行存根,以返回对协议的模拟,并对模拟的协议“实现”的功能之一表示期望。
编辑-下面是一个示例:
有一个协议,它的实现:
(defprotocol Thiny (go-bump [_ _]))
(deftype TheThing []
Thiny
(go-bump [_ _] 23))有一个函数返回协议的实现:
(defn gimme [] (TheThing.))TheThing可能是一个DB或网络连接,或者是您想要在测试中摆脱的其他一些讨厌的东西。
然后,有一个我想测试的函数:
(defn test-me [n]
(let [t (gimme)]
(-> t (go-bump n))))我想确定它叫n。
这是我第一次尝试创建一个测试。但是这还只是一半,我想在gimme返回的薄纸上建立起预期。
(fact
(test-me 42) => 42
(provided (gimme) => (reify Thiny (go-bump [_ n] n))))发布于 2013-10-28 16:01:57
为了子孙后代。下面是一个有效的测试:
(fact
(test-me 42) => 42
(provided (gimme) => :the-thingy)
(provided (go-bump :the-thingy 42) => 42))诀窍是使用相互绑定的多个提供的语句。
我们的观察。同样的测试方式不适用于使用其他语法在协议上调用函数的函数。不知道为什么。
(defn test-me2 [n]
(let [t (gimme)]
(.go-bump t n)))发布于 2013-10-28 14:04:25
模拟协议应该与模拟函数没有什么不同,您需要考虑第一个驱散参数是this,因此模拟函数应该考虑这种类型。
例如,给定一个协议P
(defprotocol P
(foo [this])
(bar-me [this] [this y]))扩展为Integer类型
(extend-protocol P
Integer
(foo [this]
(+ this 4))
(bar-me [this]
(* this 5))
(bar-me [this y]
(+ this y)))您可以先检查几件事情,没有Long的实现
(foo 3)
=> IllegalArgumentException No implementation of method: :foo of
protocol: #'P found for class: java.lang.Long
clojure.core/-cache-protocol-fn (core_deftype.clj:541)为ints预期的工作
(foo (int 3))
=> 7现在,根据需要定义事实并提供协议功能:
(fact
(foo (int 3)) => 7
(provided (foo 3) => 8))在这种情况下,它正确地失败了,因为模拟正在为指定的输入返回8而不是7。
FAIL at (test.clj:20)
Expected: 7
Actual: 8如果值模拟还不够,并且需要提供替代实现,那么看看与-redefs,您可以用它包装测试的函数。
=> (defn f [] false)
=> (println (f))
;; false
=> (with-redefs-fn {#'f (fn [] true)}
#(println (f)))
;; true此外,还有一些用于运行时调度模拟的在GitHub上讨论his。
https://stackoverflow.com/questions/19633633
复制相似问题