2013-06-12 1 views
6

상황 : 저는 B 함수를 호출하는 단위 테스트 함수 A를 시도하고 있습니다. 함수 B는 slingshot try + 블록에서 특정 상황에서 호출됩니다 그것은 새총 던지기 +를 사용하여 던질 수 있습니다. 나는 midje 테스트에서 함수 B를 모의하고 싶다. 그래서 try + 블록의 catch가 실제로 잡을 것 같은 것을 리턴한다. 나는 던질 권리가있는 것을 만들 수없는 것 같습니다. 여기에 코드와 테스트를 실질적으로 줄여 스케치는 다음과 같습니다왜 슬링 샷을 던져서 함수를 조롱하기 위해 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 문을 통해 실행될 때 이것을 볼 수 있습니다. 그러나, 나는 무엇이든 테스트를받을 수 없습니다.

또한 아래의 코드를 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"))) 

답변

2

(here, herehere를 참조)이 throw 가능 객체를 생성하는 방법에 대한 새총의 코드를 따라 난 그냥 throw ING 작동 것 throw 가능 객체를 생성하는 다음 (다소 인위적인) 방법을 발견했다.

(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}'라고 말할 수있는 함수를 만들었습니다. ] 내 문제를 해결해 주셔서 고맙습니다. (slingshot.support/get-throwable (slingshot.support/make-context 예외 맵 (str "throw + :"맵) (slingshot.support/stack-trace) {})) –

3

:

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

사용 예 :

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

장점은 새총의 내부 구현에 의존하지 않는 것입니다.

+1

이 대답은 받아 들여진 대답이어야합니다. 간단하고 강력합니다. 주요 slingshot API에 의존하기 때문입니다. – neverfox