[Contestj-developer] contestj/contestj2/src/main/java/org/contestj/mockservice MockInvocationHandl
Status: Inactive
Brought to you by:
thomasra
|
From: Ståle P. <st...@us...> - 2007-06-20 14:54:22
|
Update of /cvsroot/contestj/contestj/contestj2/src/main/java/org/contestj/mockservice In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv14426/contestj2/src/main/java/org/contestj/mockservice Added Files: MockInvocationHandler.java MockService.java ContestJSetup.java MockMethod.java Log Message: Initial upload of Contestj2 even though it supports most of the Contestj features its not ready to be used atm. --- NEW FILE: MockMethod.java --- package org.contestj.mockservice; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import org.apache.log4j.Logger; /** * This class wraps a java.lang.reflect.Method object, and implements the * ability to set the desired return value etc. * * Part of the contestJ test framework. * * Distributed under the terms of the LGPL. * * Copyright (C) 2005 Thomas Roka-Aardal * * @author Thomas Roka-Aardal * * */ public class MockMethod { private Method method = null; private Class originatingClass = null; private ArrayList returnValues = null; private ArrayList arguments = null; private RuntimeException exception = null; private long waitTime = 0L; private boolean timedOnly = false; private long timeToWait = 0L; private MockInvocationHandler invocationHandler; private Logger logger = Logger.getLogger(MockMethod.class); /** * This constructor is calls the other constructor for void methods (using * new Class[0] as the arguments). * * @param originatingClass * @param method */ public MockMethod(String originatingClass, String method) { this(originatingClass, method, new Class[0]); } /** * This constructor looks up the method on the class and initializes the local * variables. * * @param originatingClass * @param method */ public MockMethod(String originatingClass, String method, Class[] methodArguments) { try { this.originatingClass = Class.forName(originatingClass); this.method = this.originatingClass.getDeclaredMethod(method, methodArguments); returnValues = new ArrayList(); arguments = new ArrayList(); } catch (Exception e) { throw new RuntimeException("Could not define mock because of reflection errors: " + e); } } public MockMethod(String originatingClass, String method, Class[] methodArguments, MockInvocationHandler invocation) { this(originatingClass, method, methodArguments); this.invocationHandler = invocation; } /** * This constructor takes Class and Method reflection objects * as arguments in order to be a lot more rigid and avoid errors * because of classes not found etc. * * @param originatingClass * @param method */ public MockMethod(String originatingClass, String method, long milliSeconds) { this(originatingClass, method); //set up the waiting time this.waitTime = milliSeconds; } /** * Set up the return value for the invocation of the method. Note that * for this to be foolproof it needs to get in an object of the same type * as the original method, else you will get classcast exceptions. * * @param returnValue */ public void setupInvoke(Object returnValue) { returnValues.add(returnValue); } /** * Set up an exception to be thrown when the invoke method is called. If this * exception is not set (defaults to null) or set to null, it will not be used, * if it is anything other than null, it will always be thrown on invoke. * * @param exception */ public void setupInvokeException(RuntimeException exception) { this.exception = exception; } public Method getMethod() { return method; } public Class getOriginatingClass() { return originatingClass; } public MockInvocationHandler getInvocationHandler() { return invocationHandler; } public void setInvocationHandler(MockInvocationHandler invHandler) { invocationHandler = invHandler; logger.debug("Setting invocation handler to: "+invHandler.toString()); } /** * Returns the first set up value or throws an exception (if the exception is not null) * * Note that this method returns FIFO according to the setupInvoke methods that were added * at the back of the array. * * @return */ public Object invoke(Object[] argument) { if(waitTime > 0) { System.out.println("Waiting for: ."+waitTime); new WaitThread(waitTime).run(); } arguments.add(argument); if(exception == null) { if(invocationHandler != null) { Object result = invocationHandler.invoke(argument); return result; } else { Iterator iter = returnValues.iterator(); Object result = null; if (iter.hasNext()) { result = iter.next(); } if(result == null && returnValues.size() == 0) { throw new RuntimeException("setupInvoke was not configured with enough return values!"); } returnValues.remove(0); System.out.println("Returning object: "+result.getClass().getName()); return result; } } throw exception; } /** * This method returns the arguments that were passed to the mock method in the * order they were called. * * @return */ public Object getArgument() { if(arguments.size() == 0) { throw new RuntimeException("getArgument was invoked without more arguments!"); } Iterator iter = arguments.iterator(); Object argument = null; while(iter.hasNext()) { argument = iter.next(); } arguments.remove(argument); return argument; } private class WaitThread extends Thread { private long waitTime; /* (non-Javadoc) * @see java.lang.Runnable#run() */ public void run() { super.run(); try { sleep(waitTime); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public WaitThread(long milliSeconds) { this.waitTime = milliSeconds; } } public boolean isTimedOnly() { return timedOnly; } public long getTimeToWait() { return timeToWait; } public void setTimedOnly(boolean timedOnly, long timeToWait) { this.timedOnly = timedOnly; this.timeToWait = timeToWait; } } --- NEW FILE: MockService.java --- /* * Created on Aug 3, 2004 * * Copyright (C) 2004 Thomas Roka-Aardal */ package org.contestj.mockservice; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; /** * This class is a singleton that holds references to mocked classes and their * settings for use in a test environment. For more information, refer to * various articles on using AspectJ and MockObjects for unit testing. * * Part of the contestJ test framework. * * Distributed under the terms of the LGPL. * * Copyright (C) 2005 Thomas Roka-Aardal * * @author Thomas Roka-Aardal * * */ public class MockService { private Logger logger = Logger.getLogger(MockService.class); private static MockService instance = new MockService(); private Map mockObjectReferences = null; private Map mockMethodReferences = null; protected MockService() { logger.debug("ContestJMockService initialized"); mockObjectReferences = new Hashtable(); mockMethodReferences = new Hashtable(); } public static MockService getInstance() { return instance; } /** * Adds a mock method to the internal map, intended to be * used to mock both static and non-static methods. * * It uses fully.qualified.classname::methodname as the key in * the private map. * * @param mockMethod */ public void addMockMethod(MockMethod mockMethod) { String classAndMethod = generateMethodKey(mockMethod.getOriginatingClass().getName(), mockMethod.getMethod().getName()); logger.debug("ContestJMockService::addMockMethod adding mock for key: " + classAndMethod); mockMethodReferences.put(classAndMethod, mockMethod); } /** * * @param mock */ public void addMock(Object mock) { String className = mock.getClass().getSuperclass().getName(); logger.debug("ContestJMockService::addMock adding mock for class: " + className); mockObjectReferences.put(className, mock); } /** * @return Mock objects in service */ public Map getMocks() { return mockObjectReferences; } /** * @return Mock methods in service */ public Map getMockMethods() { return mockMethodReferences; } /** * Prints mock object keys to System.out for debug purposes. */ public void printMockObjectKeysToSystemOut() { String mocklist = ""; Iterator iterKeys = mockObjectReferences.keySet().iterator(); int counter = 0; while (iterKeys.hasNext()) { Object key = iterKeys.next(); mocklist += "\"" + key + "\" "; counter++; } if (mocklist.equals("")) { System.out.println("[ContestJMockService] There are no keys for mock objects in ContestJMockService right now."); } else { System.out.println("[ContestJMockService] Keys (count=" + counter + ") for mock objects in ContestJMockService right now: " + mocklist); } } /** * Prints mock method keys to System.out for debug purposes. */ public void printMockMethodKeysToSystemOut() { String mocklist = ""; Iterator iterKeys = mockMethodReferences.keySet().iterator(); int counter = 0; while (iterKeys.hasNext()) { Object key = iterKeys.next(); mocklist += "\"" + key + "\" "; counter++; } if (mocklist.equals("")) { System.out.println("[ContestJMockService] There are no keys for mock methods in ContestJMockService right now."); } else { System.out.println("[ContestJMockService] Keys (count=" + counter + ") for mock methods in ContestJMockService right now: " + mocklist); } } /** * * @param interfaceToMock * @return */ public Object getMockForInterface(Class interfaceToMock) { logger.debug("ContestJMockService::getMockForInterface requesting mock for interface: " + interfaceToMock); Set keys = mockObjectReferences.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext();) { String element = (String) iter.next(); logger.debug("ContestJMockService::getMockForInterface checking against registered mock: " + element); if(element.equals(interfaceToMock.getName())) { logger.debug("ContestJMockService::getMockForInterface found mock for interface: " + interfaceToMock); return mockObjectReferences.get(element); } } logger.debug("ContestJMockService::getMockForInterface didn't find mock for interface: " + interfaceToMock); return null; } /** * This method checks the private method map to see if a certain method * is registered on the service. If it is, it is returned. * * @param method * @return */ public MockMethod getMockForMethod(String className, String methodName) { String keyToFind = generateMethodKey(className, methodName); System.out.println("ContestJMockService::getMockForMethod requesting mock for method: " + keyToFind); Set keys = mockMethodReferences.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext();) { String key = (String) iter.next(); if(key.equals(keyToFind)) { logger.debug("ContestJMockService::getMockForMethod found mock for method: " + keyToFind); return (MockMethod) mockMethodReferences.get(key); } } logger.debug("ContestJMockService::getMockForMethod didn't find mock for method: " + keyToFind); return null; } /** * @param mockMethod * @return */ private String generateMethodKey(String className, String methodName) { String classAndMethod = new StringBuffer().append(className) .append("::") .append(methodName) .toString(); return classAndMethod; } /** * Resets the mocks in the singleton * */ public void reset() { logger.debug("ContestJMockService resetting values"); mockMethodReferences.clear(); mockObjectReferences.clear(); } } --- NEW FILE: MockInvocationHandler.java --- package org.contestj.mockservice; /** * MockInvocationHandler. * * @author <a href="st...@gm...">Stale W. Pedersen</a> * @version $Revision: 1.1 $ */ public interface MockInvocationHandler { public Object invoke(Object[] o); } --- NEW FILE: ContestJSetup.java --- package org.contestj.mockservice; import org.contestj.introduction.Mock; /** * A simple replacement of the original ContestJSetup. * * @author <a href="st...@gm...">Stale W. Pedersen</a> * @version $Revision: 1.1 $ */ public class ContestJSetup { /** * This method primes the mock method with a return value so that it returns expected * results. This will only work on classes thats already been duplicated by * Duplicator. * * Note that for use with varargs in Java5 you need to tell this method that the arguments * are an array (because that is how the bytecode works). So if you have a method: * doStuff(String ... args) * ...you need to tell this method that the arguments are an array of strings (String[].class). * * Multiple invocations on this method stacks return values. * * @param instance * @param method * @param arguments * @param returnValue */ public static void setup(Object instance, String method, Class[] arguments, Object returnValue) { if(arguments != null && arguments.length > 0) { ((Mock) instance).setupMock(method, arguments, returnValue); } else { ((Mock) instance).setupMock(method, returnValue); } } /** * This method primes the mock method with an exception value so that it returns expected * results. * * Note that for use with varargs in Java5 you need to tell this method that the arguments * are an array (because that is how the bytecode works). So if you have a method: * doStuff(String ... args) * ...you need to tell this method that the arguments are an array of strings (String[].class). * * * @param method * @param arguments * @param exception */ public static void setupException(Object instance, String method, Class[] arguments, Object exception) { if(arguments != null && arguments.length > 0) { ((Mock) instance).setupExceptionMock(method, arguments, new Exception(exception.toString())); } else { ((Mock) instance).setupExceptionMock(method, new Exception(exception.toString())); } } } |