为什么我不能使用midje来模拟使用弹弓投掷+抛出的函数

Mat*_*ley 6 unit-testing exception-handling clojure mocking midje

这是情况:我正在尝试单元测试函数A调用函数B.函数B在弹弓try +块中调用,在某些情况下它可以使用弹弓投掷+.我想在midje测试中模拟函数B,以便返回try + block中的catch实际捕获的内容.我似乎无法创造出正确的东西.这是代码和测试的大致缩略图:

(defn function-A
  [param]
  (try+
    (function-B param)
    (catch [:type :user-not-found]
      (do-something))))

(defn function-B
  [param]
  (throw+ [:type :user-not-found]))

(fact "do-something is called"
  (function-A "param") => (whatever is the result of calling do-something)
  (provided
    (function-B "param") =throws=> (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
                                                                {:object {:type :user-not-found}, :environment {}}
                                                                nil)))
Run Code Online (Sandbox Code Playgroud)

我正在抛出的ExceptionInfo似乎是正确的.当我的应用程序通过大量的prn语句运行时,我可以看到这一点.但是,无论我尝试什么,我都无法让测试工作.

我还在repl中尝试了下面的代码,看看我是否能理解这个问题.然而,虽然两段代码似乎都涉及相同的异常,但只有一个(纯粹的弹弓)设法捕获并打印"抓住它".我想如果我能理解为什么一个有效而另一个无法有效,我就可以通过单元测试解决问题.

(try+
  (try
    (throw+ {:type :user-not-found})
    (catch Exception e
      (prn "Caught:  " e)
      (prn "Class:   " (.getClass e))
      (prn "Message: " (.getMessage e))
      (prn "Cause:   " (.getCause e))
      (prn "Data:    " (.getData e))
      (throw e)))
  (catch [:type :user-not-found] p
    (prn "caught it")))

(try+
  (try
    (throw (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
                                        {:object {:type :user-not-found}, :environment {}}
                                        nil))
    (catch Exception e
      (prn "Caught:  " e)
      (prn "Class:   " (.getClass e))
      (prn "Message: " (.getMessage e))
      (prn "Cause:   " (.getCause e))
      (prn "Data:    " (.getData e))
      (throw e)))
  (catch [:type :user-not-found] p
    (prn "caught it")))
Run Code Online (Sandbox Code Playgroud)

jua*_*rro 2

按照 slingshot 的代码了解如何生成 throwable(请参阅此处此处此处),我发现了以下(有点人为的)方法来生成仅在 ing 时即可工作的 throwable throw

(s/get-throwable (s/make-context {:type :user-not-found} "throw+: {:type :user-not-found}" (s/stack-trace) {}))
Run Code Online (Sandbox Code Playgroud)

这会呈现您期望的示例结果。

(try+
  (try
    (throw (s/get-throwable (s/make-context {:type :user-not-found} "throw+: {:type :user-not-found}" (s/stack-trace) {})))
    (catch Exception e
      (prn "Caught:  " e)
      (prn "Class:   " (.getClass e))
      (prn "Message: " (.getMessage e))
      (prn "Cause:   " (.getCause e))
      (prn "Data:    " (.getData e))
      (throw e)))
  (catch [:type :user-not-found] p
    (prn "caught it")))
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。