为什么我不能将-recrefs提取为单独的函数?

时间:2016-06-22 15:34:34

标签: clojure

我有一个我想测试的功能。

(defn -main
  [& args]
  (let [port (Integer/parseInt (or (first args) "8080"))]
    (run-jetty
      app
      {:port port})))

出于显而易见的原因,我需要嘲笑run-jetty,因此我使用with-redefs来验证是否传递了正确的args。这非常有效。

(it "should overide the port with first arg"
        (with-redefs [run-jetty (fn [handler opts] [handler opts])]
            (should= 8081 (jetty-port (underTest/-main "8081")))))

我想提取with-redefs调用,因为我在几个测试中使用它,所以我尝试了这个:

(defn mock-jetty
  [test]
  (with-redefs [run-jetty (fn [handler args] [handler args])] test))

(describe "The app"
  (it "should default to port 8080"
      (mock-jetty
        (should= 8080 (jetty-port (underTest/-main))))))

此测试调用真正的run-jetty函数并启动服务器。为什么会这样?

修改

将提取更改为宏:

(defmacro mock-jetty
  [someTest]
  `(with-redefs [run-jetty (fn [handler args] [handler args])] ~someTest))

(describe "The app"
  (it "should default to port 8080"
      (mock-jetty
        (should= 8080 (jetty-port (underTest/-main))))))

抛出此异常: Can't use qualified name as parameter: boost-bin.handler-test/handler

1 个答案:

答案 0 :(得分:2)

我猜,它与with-redefs是一个宏的事实有关。所以当你在代码中直接调用它时,它会在redefs的上下文中执行test body,而当你将它移到函数时,正在执行body (should= 8080 (jetty-port (underTest/-main))),然后传递给macro(因为它总是发生在函数' params)

要使其正常工作,您可以将mock-jetty重写为宏:

(defmacro mock-jetty
  [test]
  `(with-redefs [run-jetty (fn [handler# args#] [handler# args#])] ~test))

我很确定这会有所帮助