Unit testing Midje中模拟协议的实现

Unit testing Midje中模拟协议的实现,unit-testing,clojure,mocking,midje,Unit Testing,Clojure,Mocking,Midje,有没有办法使用类似于“提供的”语法的东西,用Midje(clojure)模拟(而不是存根)协议函数 这与中的问题相似,但带有嘲弄 更详细地说:我有一个协议和一个函数,返回实现它的东西。我想存根函数以返回协议的模拟,并且我想注册对模拟协议“实现”的一个函数的期望 编辑-下面是一个示例: 有一个协议及其实现: (defprotocol Thiny (go-bump [_ _])) (deftype TheThing [] Thiny (go-bump [_ _] 23)) 有一个函数返回协

有没有办法使用类似于“提供的”语法的东西,用Midje(clojure)模拟(而不是存根)协议函数

这与中的问题相似,但带有嘲弄

更详细地说:我有一个协议和一个函数,返回实现它的东西。我想存根函数以返回协议的模拟,并且我想注册对模拟协议“实现”的一个函数的期望

编辑-下面是一个示例:

有一个协议及其实现:

(defprotocol Thiny (go-bump [_ _]))
(deftype TheThing []
  Thiny
  (go-bump [_ _] 23))
有一个函数返回协议的实现:

(defn gimme [] (TheThing.))
这可能是一个数据库或网络连接或其他一些你想在测试中摆脱的讨厌的东西

然后,我想测试一个函数:

(defn test-me [n]
  (let [t (gimme)]
    (-> t (go-bump n))))
我想确保它调用go bump with n

这是我第一次尝试创建测试。但这只是完成了一半,我想对gimme返回的东西设定期望值:


嘲弄协议和MOCKIN函数没有什么不同,你需要考虑第一个DISCHORD参数是<代码>这个< /代码>,所以嘲讽函数应该考虑到这个类型。 例如,给定一个协议

p

(defprotocol P 
  (foo [this]) 
  (bar-me [this] [this y]))
扩展为类型
整数

(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
如果值模拟还不够,您需要提供一个替代的实现,请看一看,您可以用它包装测试过的函数

 => (defn f [] false)
 => (println (f))
 ;; false
 => (with-redefs-fn {#'f (fn [] true)}
 #(println (f)))
 ;; true

对于运行时调度mock,还有两种选择。

面向后代。下面是一个工作测试:

(fact
  (test-me 42) => 42
  (provided (gimme) => :the-thingy)
  (provided (go-bump :the-thingy 42) => 42))
诀窍是使用多个相互关联的提供语句

威德观察。对于使用其他语法调用协议函数的函数,同样的测试方法不适用。不知道为什么


我不知道这是如何解决我的问题的。我需要对函数返回的内容设置期望值。用一个例子更新了我的问题。Midje实体模型只是返回数据的实体模型,您可以指定输入的预期输出,但不是替代实现,还有一个问题是,
提供的
最终值在编译时得到评估,因此,您将对函数的返回值进行评估。查看这两篇关于mock的文章:,请参阅编辑的
with redefs fn
模拟函数实现示例我仍然没有得到它。很抱歉模拟gimme函数不是问题所在。问题在于对它的回报设定期望。你是说这是不可能的吗?好吧,你避免创建
分派对象
,关于github问题的一些建议也是关于模仿
defrecord
这是一个老问题,但它仍然相关。显然,您不能模拟协议上的函数,除非您还模拟创建协议实现的对象的创建。或者类似的。
(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)))