2013-06-12 13 views
6

Hier ist die Situation: Ich versuche Einheit Test Funktion A, die Funktion B ruft Funktion B aufgerufen wird in einem Schleuderversuch + Block und unter bestimmten Umständen aufgerufen es kann mit einem Schleuder Wurf werfen. Ich möchte Funktion B in einem Midje-Test nachahmen, so dass es etwas zurückgibt, das der Fang im try + -Block tatsächlich fangen wird. Ich kann nicht scheinen, das Richtige zu schaffen, um zu werfen. Hier ist eine wesentlich verkürzte Skizze des Codes und der Test:Warum kann ich nicht Midje verwenden, um eine Funktion zu verspotten, die mit Slingshot werfen wirft +

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

Die ExceptionInfo, dass ich Werfen roughtly das Richtige zu sein scheint. Ich kann das sehen, wenn meine Anwendung zahlreiche prn-Anweisungen durchläuft. Wie auch immer ich es versuche, ich kann den Test nicht zum Laufen bringen.

Ich versuchte auch das Bit Code unten in einem repl, um zu sehen, ob ich das Problem verstehen konnte. Obwohl beide Codeabschnitte identische Exceptions zu enthalten scheinen, schafft es nur einer (der reine Slingshot), "gefangen" zu werden und zu drucken. Ich denke, wenn ich verstehen könnte, warum einer arbeitet und der andere nicht, wäre ich in der Lage, das Problem mit dem Komponententest zu lösen.

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

Antwort

2

Schleuder Code Nach, wie es einen throwable erzeugt (siehe here, here und here), fand ich den folgenden (etwas gekünstelt) Weg, um eine throwable zur Erzeugung, die, wenn nur throw ing funktionieren würde.

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

Welche ergibt das Ergebnis, das Sie von Ihrem Beispiel erwartet haben.

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

Ich hoffe, es hilft.

+1

Das ist brilliant. Es funktioniert sicherlich. In meinem Unit-Test-Code habe ich gerade eine Funktion erstellt, mit der ich '= throws => (slingshot-exception {: type: user-not-found}' sagen kann. Die Funktion ist: '(defn slingshot-exception [exception-map ] (slingshot.support/get-throwable (slingshot.support/make-context Ausnahme-Map (str "throw +:" Karte) (slingshot.support/stack-trace) {}))) '. Vielen Dank für die Lösung meines Problems –

3

, dass eine wirklich späte Antwort ist, aber was ist die folgende Lösung:

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

Anwendungsbeispiel:

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

Der Vorteil ist, dass Sie nicht auf interne Implementierung von Schleuder verlasse.

+1

Dies sollte die akzeptierte Antwort sein, einfach und robust, da es auf der Haupt-Slingshot-API beruht. – neverfox