Using a Java Proxy to create Mockups for tests

Today I had the first chance to use the Java Proxy class to create a Mockup class for unit testing. Few people know that it is possible to create mock objects in Java without using an external framework.

I wanted to test a method that took as argument an instance of an Interface and I did not want to create an anonymous class to implement only the method I needed. I remembered having read here about java.lang.reflect.Proxy . As the name says, this class is a way to implement the Proxy pattern.

The proxy pattern is a pattern from the original Gof that creates a wrapper to the real object to provide extra functionality or just to forward the call.

I made a small example with tests on github .

I created an interface called Person


public interface Person {

    String getName();

    String getJob();

    int getAge();
}

All I needed was to implement the getName() method, but I also implemented the getAge() one to show that it works also with methods that return primitives.

Implementing a proxy is very easy:

  1. Implement an InvocationHandler. This is interface has just one method with 3 arguments: the Proxy itself, the Method that was called (the Method class from Java reflection) and the array of arguments the method is called with.
  2. Invoke Proxy.newProxyInstance passing a ClassLoader, the array of Interfaces that will be implemented and the handler that will be used
  3. Cast the generated Object to the desired Interface.

InvocationHandler h = (Object proxy, Method method, Object[] args1) {
switch (method.getName()) {
    case "getName":
        return "Enrico";
    case "getAge":
        return 36;
    case "getJob":
        throw new IllegalArgumentException(method.getName() + " is not supported");
}
    throw new UnsupportedOperationException("Not supported yet.");
};

Person p = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, h);

the image was taken from here

 

Leave a Comment

Your email address will not be published. Required fields are marked *