2013-01-22 5 views
5

Ich versuche, die RabbitMQ-Interaktionen zu stopfen, da diese nicht wirklich der Hauptzweck der Anwendung sind, die ich schreibe.Wie stoße ich langohr RabbitMQ Interaktionen in clojure?

Also habe ich versucht, in meinen Tests die Funktionen rebinding Langohr wie so:

(defn stub [ch] 
    (langohr.basic/ack ch 1)) 

(deftest test-stub 
    (with-redefs [langohr.basic/ack (fn [a1 a2] true)] 
    (is (= true (stub "dummy"))))) 

Wenn ich den Test mit lein test laufen, erhalte ich eine

java.lang.ClassCastException: 
redwood.env_test$fn__2210$fn__2211 cannot be cast to clojure.lang.IFn$OLO 

Ich habe versucht, mehrere andere Möglichkeiten, einschließlich verschiedener Test-Frameworks, um die Langohr-Lib-Funktionen ohne Fortschritt neu zu definieren oder zu binden.

Ich habe andere Szenarien getestet und habe erfolgreich Cheshire (JSON Parsing Clojure Lib) -Funktionen mit der obigen Code-Struktur. Ich bitte demütig um Hilfe zu verstehen, warum meine langohr Stubs nicht funktionieren und für Tipps, wie ich das auf elegante Weise tun kann.

Antwort

6

Die ClassCastException tritt auf, weil langohr.basic/ack eine Funktion ist, die ein primitives Argument verwendet - speziell vom Typ clojure.lang.IFn $ OLO, wobei OLO für "object, long, object" steht.

Sie müssen es vom gleichen Typ neu definieren. Versuchen Sie dies:

(with-redefs [langohr.basic/ack (fn [a1 ^long a2] true)] ...) 
+1

Danke Herr Perkins, ich schaute in den Clojure-Code und sah, wo die OLO-Funktion in Java. Ich bin verwirrt, weil, wenn ich zu einer Funktion meiner Wahl neu bin, warum sollte es wichtig sein, was meine Funktionsargumenttypen sein sollten? Ich dachte, die neue Var wäre unabhängig von der alten. Langohr hat auch eine 'langohr.basic/nack'-Funktion, die mit der gleichen Implementierung wie ack geschrieben wurde, aber diese Funktion wurde erfolgreich ohne Klassenkürzel neu definiert. – Phong

+2

Es ist wichtig, weil die aufrufende Funktion ('stub' in Ihrem Beispiel) in Code kompiliert wird, der die Variable' 'langhor.basic/ack' 'dereferenziert und dann versucht, das Ergebnis in' IFn $ OLO' zu konvertieren. Dies geschieht, weil der Compiler erkennt, dass sich 'langhor.basic/ack' zum Zeitpunkt der Kompilierung auf eine Funktion dieses Typs bezieht und die Umwandlung durchführen muss, um ein primitives (ungeboxtes) long übergeben zu können. Ohne einige Code zu sehen, kann ich nicht sagen, warum "Nack" Ihnen nicht den gleichen Fehler gibt, aber bedenken Sie, dass es der Aufruf an 'stub' ist, und nicht das redef selbst, das scheitert, und das Geben Sie zur Kompilierungszeit ein. –

+0

Danke nochmal Herr Perkins, sehr aufschlussreich und nützlich. – Phong

Verwandte Themen