6

I'm trying to stub the RabbitMQ interactions, as those aren't really the main purpose of the application I'm writing.

So, I've tried rebinding the langohr functions in my tests like 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")))))

When I run the test with lein test, I get a

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

I've been trying several other ways including different test frameworks to redefine or rebind the langohr lib functions with no progress.

I've tested other scenarios and I've successfully stubbed cheshire (json parsing clojure lib) functions with the above code structure. I humbly request assistance in understanding why my langohr stubs aren't working and for tips on how I can do this in an elegant manner.

Brad Koch
  • 19,267
  • 19
  • 110
  • 137
Phong
  • 93
  • 7

1 Answers1

6

The ClassCastException occurs because langohr.basic/ack is a function that takes a primitive argument - specifically, it is of type clojure.lang.IFn$OLO, where the OLO stands for "object, long, object".

You have to redef it be of the same type. Try this:

(with-redefs [langohr.basic/ack (fn [a1 ^long a2] true)] ...)
Chris Perkins
  • 3,350
  • 4
  • 21
  • 16
  • 1
    Thanks Mr. Perkins, I looked into the clojure code and saw where the OLO function in java. I'm confused because when I rebind to a function of my choosing, why should it matter what my function argument types should be? I thought the new var was independent of the old. Langohr also has a `langohr.basic/nack` function written with the same implementation as ack, yet this function was successfully redefed without the classcastexception. – Phong Jan 23 '13 at 15:28
  • 2
    It matters because the calling function (`stub` in your example) gets compiled into code that derefs the var `langhor.basic/ack` and then tries to cast the result to `IFn$OLO`. This happens because the compiler sees that, at compile-time, `langhor.basic/ack` refers to a function of that type, and it needs to do the cast in order to be able to pass a primitive (unboxed) long. Without seeing some code, I can't say why `nack` is not giving you the same error, but keep in mind that it is the call to `stub`, and not the redef itself, that fails, and that the type at compile-time matters. – Chris Perkins Jan 23 '13 at 16:29