Java Programming Tutorials

Java programming tutorials with many code examples!

Clojure mock Java class

Clojure mock Java class

In this tutorial we’re going to show how to use Clojure proxy to mock Java classes and provide own functionality for methods.

Proxy class with no-arg constructor

Calls superclass default constructor:

(def my-list
  (proxy [ArrayList] []
    (get [i] 42)))

Let’s use it:

user> (.get my-list 10)
42

No matching ctor found for class

Superclass has no no-arg constructor:

(proxy [FileInputStream] []
        (read []
          42))

Produces an exception, because there’s no no-arg constructor in FileInputStream class:

CompilerException java.lang.IllegalArgumentException: No matching ctor found for class user.proxy$java.io.FileInputStream$ff19274a

Proxy java class with constructor

We have to provide obligatory constructor parameter (here “/proc/version”), that will be passed to superclass:

;; To count calls and return predictive values:
(def counter (atom 0))

(def my-mock
  (proxy [FileInputStream] ["/proc/version"]
    (read []
      (swap! counter inc))))

Now our version of read method may be called as expected:

user> (.read my-mock)
1
user> (.read my-mock)
2
user> (.read my-mock)
3

Overload mocked method

(def counter (atom 0))

(def my-mock
  (proxy [FileInputStream] ["/proc/version"]
    (read
      ([] (swap! counter inc)) ; read()
      ([^bytes arr]            ; read(byte[])
       (aset-byte arr 0 42)
       (swap! counter inc)))))

read(byte[]) can be called like this:

user> (.read my-mock (byte-array 3))
1
user> (.read my-mock (byte-array 3))
2
Share with the World!