L'etat, c'est moi
Mere Complexities sells the consulting and development services of me, Paul Wilson.
Conferences
Archive
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()); } }}