在clojure测试中,如何在测试一个功能时模拟出多个方法?

In clojure test, how to mock out multiple methods when testing one function?

我正在为我的应用程序中的一个相当大的函数编写 clojure.test 单元测试。此函数多次调用数据库和外部 REST 服务并进行一些计算。 比如我要测试的函数是这样的

(defn myfunc [id]
   (let[
        w (some-security-call id)
        x (some-db-call id)
        y  (some-REST-call x)
        z ( some-audit-call y)

       ]
       (-> y :somekey )))

为了测试此方法,我想删除或重新定义“some-audit-call”和“some-security-call”。 Clojure 的 with-redefs-fn 一次只能重新定义一个方法。

是否有一种标准的方法来模拟正在单元测试的函数中使用的多个函数?

with-redefs 可以使用任意多的函数。这是我实际生产测试中经过编辑的示例。

(with-redefs [namespace/redacted            (constantly [])
              namespace/redacted                 (fn [& args] (async/go namespace/redacted))
              namespace/redacted        (constantly [2 4])
              namespace/redacted                (fn [& args] (namespace/redacted sample-redacted-ads))
              namespace/redacted                (fn [_ _ redacted & _]
                                                  (async/go (cond-> namespace/redacted
                                                              namespace/redacted (dissoc redacted))))
              namespace/redacted                   (fn [& args] (async/go nil))
              namespace/redacted       fake-redacted
              namespace/redacted       fake-redacted
              namespace/redacted      namespace/redacted
              namespace/redacted       (go (constantly []))
              namespace/redacted               (fn [_] [])
              namespace/redacted      namespace/redacted
              namespace/redacted      namespace/redacted
              namespace/redacted                        (fn [_] {:redacted "redacted"})]
  (is (= "redacted"
         (get-in (<!!
                  )
                 ))
      "We should return the redacted if we don't pass it in")
  ... many more tests here ...

)

如果你需要重新定义一个函数,而这个函数被你想重新定义的另一个函数使用,那么你必须嵌套对 with-redef 的调用。这有时会让人们认为 with-redefs 只适用于一个函数。

您可能不想使用 with-redefs-fn,除非您知道自己有特定原因。