状況は次のとおりです: 関数 B を呼び出す関数 A を単体テストしようとしています。関数 B を midje テストでモックして、try+ ブロックの 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)))
私がスローしている ExceptionInfo は、ほぼ正しいようです。これは、アプリケーションが多数の prn ステートメントを実行しているときに確認できます。しかし、私が何をしようとしても、テストを機能させることができません。
また、問題を理解できるかどうかを確認するために、repl で以下のコードを少し試しました。ただし、コードの両方の部分には同一の例外が含まれているように見えますが、1 つ (純粋なスリングショットのもの) だけが「キャッチされた」をキャッチして出力することができます。一方が機能し、他方が機能しない理由を理解できれば、単体テストで問題を解決できると思います。
(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")))