Why can't I use midje to make fun of a function that throws using slingshot throw +

Here's the situation: I'm trying to execute unit test function A, which calls function B. Function B is called in slingshot try + block and, in certain circumstances, can be thrown using a throw of slingshot +. I want to make fun of function B in the middle test so that it returns what catch will catch in the try + block. I can't seem to create the right thing. Here is a substantially shortened sketch of the code and 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 throw seems to be absolutely correct. I see this when my application runs through numerous prn commands. However, no matter what I try, I cannot get the test to work.

I also tried the code bit below in the replica to see if I can understand the problem. However, although both pieces of code seem to be related to the same exceptions, only one (pure slingshot) manages to catch and print the “caught”. I think that if I could understand why one works and the other doesn't, I could 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"))) 
+6
source share
2 answers

After the slingshot code for how it generated the throwable (see here , here and here ), I found the following (somewhat contrived) way to create a throw that would work when just throwing.

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

Which gives the result that you expected from your example.

 (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"))) 

Hope this helps.

+2
source

This is a really late answer, but what about the following solution:

 (defn ex+ [cause] (try (throw+ cause) (catch Throwable ex ex))) 

Usage example:

 (broken-fn) =throws=> (ex+ {:type :user-not-found}) 

The advantage is that you do not rely on Slingshot's internal implementation.

+3
source

Source: https://habr.com/ru/post/947125/


All Articles