Sunday, 3 August 2008

Defensive Coding

Google Testing recently recommended against being defensive. The rationale behind this was that testers found it easier to simply pass a null when testing than passing in a constructed object. I disagree with this. Creating a null object either with an existing mock object framework or by using the proxy capabilities in Java makes passing a null object no harder than passing null.
Now some codez:
package ihaztehcodez.nullobject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import static
java.lang.reflect.Proxy.newProxyInstance;

/** Provides a simple alternative to passing null.
 * @author Mike Lee
 */
public class NullObjectFactory {
      /** Utility class, should never be created. */
      private NullObjectFactory() { }
     
      public static T createNullObject(Class<T> clazz) {
            return (T) newProxyInstance(ClassLoader.getSystemClassLoader(),
                  new Class [] { clazz }, new SadInvocationHandler() );
      }
}

class SadInvocationHandler implements InvocationHandler {
      public  Object    invoke(Object proxy, Method method, Object[] args) {
            throw new IllegalStateException("Proxy does not support method calls.");
      }
}


package ihaztehcodez.fourtehnalzobj;

import static ihaztehcodez.fourtehnalzobj.NullObjectFactory.createNullObject;

public class NullObjectFactoryExample {
      public void testThingie() {
            Thingie thingie = new Thingie(createNullObject(Whatsit.class));
      }
}

class Thingie {
      Thingie(Whatsit whatsit) {
      }
}

interface Whatsit {
}

0 comments: