2013-06-12 4 views
6

Вот такая ситуация: я пытаюсь выполнить функцию тестирования A, которая вызывает функцию B. Функция B вызывается в slingshot try + block и при определенных обстоятельствах он может бросить, используя бросок рогатки +. Я хочу высмеять функцию B в среднем тесте, чтобы он возвращал то, что поймает catch в блоке try +. Кажется, я не могу создать правильную вещь. Вот, по существу, сокращенный набросок кода и испытания:Почему я не могу использовать midje для издевки функции, которая бросает с помощью броска рогатки +

(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, что я метания, кажется, roughtly правильно. Я вижу это, когда мое приложение работает через многочисленные команды prn. Однако, что бы я ни пытался, я не могу заставить тест работать.

Я также попробовал немного кода ниже в реплике, чтобы узнать, могу ли я понять проблему. Однако, хотя оба фрагмента кода, похоже, связаны с одинаковыми исключениями, только один (чистый рогатка) удается поймать и распечатать «поймал». Я думаю, что если бы я мог понять, почему один работает, а другой нет, я бы смог решить проблему с модульным тестом.

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

ответ

2

После кода Рогатка для как генерируется Throwable (см here, here и here), я обнаружил следующее (несколько надуманный) способ для создания метательного, который будет работать, если только throw Ing.

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

Что дает результат, который вы ожидали от вашего примера.

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

Надеюсь, это поможет.

+1

Это великолепно. Это, безусловно, работает. В моем модульном тестовом коде я просто создал функцию, позволяющую мне сказать '= throws => (slingshot-exception {: type: user-not-found}'. Функция: '(defn slingshot-exception [exception-map ] (slingshot.support/get-throwable (slingshot.support/make-context exception-map (str "throw +:" map) (slingshot.support/stack-trace) {}))) '. Большое спасибо за решение моей проблемы –

3

Это действительно поздно ответ, но что о следующем растворе:

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

Пример использования:

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

Преимущество заключается в том, что вы не полагаться на внутреннюю реализацию Slingshot.

+1

Это должен быть принятый ответ. Простой и надежный, поскольку он зависит от основного API-интерфейса slingshot. – neverfox