Here's the situation: I'm trying to unit test function A that calls function B. Function B is called in a slingshot try+ block and under certain circumstances it can throw using a slingshot throw+. I want to mock function B in a midje test so that it returns something that the catch in the try+ block will actually catch. I can't seem to create the right thing to throw though. Here's a substantially abbreviated sketch of the code and the test:
(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)))
The ExceptionInfo that I'm throwing seems to be roughtly the right thing. I can see this when my application is running through numerous prn statements. However, whatever I try, I can't get the test to work.
I also tried the bit of code below in a repl to see whether I could understand the problem. However, whilst both pieces of code seem to involve identical Exceptions, only one (the pure slingshot one) manages to catch and print "caught it". I think that if I could understand why one works and the other doesn't, I would be able to solve the problem with the unit test.
(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")))
=throws=> (slingshot-exception {:type :user-not-found}
. The function is:(defn slingshot-exception [exception-map] (slingshot.support/get-throwable (slingshot.support/make-context exception-map (str "throw+: " map) (slingshot.support/stack-trace) {})))
. Many thanks for solving my problem. – Hoiden