Easy Peasy Mock
For various reasons, that I may go into later, I gave up Jmock a few months ago. I still find that fake implementations are useful to have in the testing toolbox. Here is a simple way of faking a subset of interface implementations: for example we might just want to fake getParameter from HttpServletRequest using a Self-Shunt.
public class TestSomeWebThing extends TestCase
{
private String _parameterNameUsed;
public void testSomeServlet() throws Exception
{
HttpServlet testee = new MyServlet();
testee.service((HttpServletRequest) DummyProxy.dummy(HttpServletRequest.class, this),
(HttpServletResponse) DummyProxy.dummy(HttpServletResponse.class, this));
assertEquals("expectedParam", _parameterNameUsed);
checkTheOtherStuffHappened();
}
/**
* Implements method from HttpServletRequet
*/
public String getParameter(String parameterName)
{
_parameterNameUsed = parameterName;
return "mavis";
}
........
}
Here is an implementation for DummyProxy:
public class DummyProxy
{
public static Object dummy(Class implementMe, Object partial)
{
return Proxy.newProxyInstance(implementMe.getClassLoader(), new Class[]{implementMe}, new Handler(partial));
}
private static class Handler implements InvocationHandler
{
private Object _partial;
public Handler(Object partial)
{
_partial = partial;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Method equivalent = findEquivalentImplementation(method);
if (equivalent == null)
{
throw new UnsupportedOperationException(method.getName() + ":" + args);
}
return equivalent.invoke(_partial, args);
}
private Method findEquivalentImplementation(Method method)
{
Method[] implementations = _partial.getClass().getMethods();
for (int i = 0; i < implementations.length; i++)
{
Method implementation = implementations[i];
if (methodNamesMatch(implementation, method) && methodParametersMatch(method, implementation))
{
return implementation;
}
}
return null;
}
private boolean methodParametersMatch(Method method, Method implementation)
{
return Arrays.equals(method.getParameterTypes(), implementation.getParameterTypes());
}
private boolean methodNamesMatch(Method implementation, Method method)
{
return implementation.getName().equals(method.getName());
}
}
}

0 Comments:
Post a Comment
<< Home