/** * */ package org.wamblee.test; import static org.mockito.Mockito.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * Resettable mock is a utility to support reset functionality for mockito. * * @author Erik Brakkee * * @param */ public class ResettableMock { private static class MockitoInvocationHandler implements MethodInterceptor { private Class _class; private T _mock; public MockitoInvocationHandler(Class aClass) { _class = aClass; _mock = mock(aClass); } public void reset() { _mock = mock(_class); } public T getMock() { return _mock; } @Override public Object intercept(Object aProxy, Method aInterceptedMethod, Object[] aArgs, MethodProxy aMethodProxy) throws Throwable { try { return aInterceptedMethod.invoke(_mock, aArgs); } catch (InvocationTargetException e) { throw e.getCause(); } } } /** * Invocation handler that delegates to the current mockito mock and allows * creation of a new mock. */ private ResettableMock.MockitoInvocationHandler _handler; /** * Proxy object to be passed to tested classes. */ private T _proxy; /** * Constructs the resettable mock. * * @param aType * Type to mock. Must be an interface or a non-final class with a * default constructor. */ public ResettableMock(Class aType) { if (!aType.isInterface()) { throw new IllegalArgumentException("Class '" + aType.getName() + "' must be an interface"); } _handler = new MockitoInvocationHandler(aType); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(aType); enhancer.setCallback(_handler); _proxy = (T) enhancer.create(); } /** * Resets the mock effectively forgetting all previous interactions and * verifications. */ public void reset() { _handler.reset(); } /** * Gets the current mock object to pass to mockito calls. * * @return Mock object. */ public T getMock() { return _handler.getMock(); } /** * Returns the proxy that your tested classes will used. * * @return Proxy object. */ public T getProxy() { return _proxy; } }