Title: [jbehave] [591] trunk/extensions/classmocks/src/java/jbehave/extensions/classmock: [EK] Can mock objects which use their constructor arguments inside their constructor.
Revision
591
Author
sirenian
Date
2006-11-29 11:03:19 -0600 (Wed, 29 Nov 2006)

Log Message

[EK] Can mock objects which use their constructor arguments inside their constructor. How cool is that?

Modified Paths

Diff

Modified: trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java (590 => 591)

--- trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java	2006-11-29 15:15:11 UTC (rev 590)
+++ trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java	2006-11-29 17:03:19 UTC (rev 591)
@@ -19,7 +19,16 @@
 	}
 	
 	private static class AClassWithNoConstructors {}
-	
+
+    
+    public static class AClassWithAComplexConstructor {
+        public AClassWithAComplexConstructor(String anObject, int primitive, char primitive2, Object[] array) {
+            anObject.compareTo("What happens if the argument is null?");
+            int i = primitive + array.length;
+        }
+        
+    }
+    
     public void shouldCreateClassObjectThatCanBeCastToTheCorrectType() {
         Mock mock = ClassMockObject.mockClass(AClass.class, "bar");
         Ensure.that(mock instanceof AClass);
@@ -54,5 +63,7 @@
 		ensureThat(expected, eq(actual));
     }
         
-    
+    public void shouldBeAbleToMockClassesWithConstructorArgs() {
+    	Mock mock = ClassMockObject.mockClass(AClassWithAComplexConstructor.class, "foo");
+    }
 }

Modified: trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java (590 => 591)

--- trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java	2006-11-29 15:15:11 UTC (rev 590)
+++ trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java	2006-11-29 17:03:19 UTC (rev 591)
@@ -76,9 +76,57 @@
 	}
     
 	private static Object[] createConstructorArgsFor(Class[] constructorArgClasses) {
-		return new Object[constructorArgClasses.length];
+		Object[] args = new Object[constructorArgClasses.length];
+		
+		for (int i = 0; i < args.length; i++) {
+			Class clazz = constructorArgClasses[i];
+			try {
+				Object result = construct(clazz);
+				args[i] = result;
+			} catch (Exception e) {
+				throw new RuntimeException("Could not mock class " + constructorArgClasses[i] + " at index " + i, e);
+			}
+		}
+		
+		return args;
 	}
 
+	private static Object construct(Class clazz) throws InstantiationException, IllegalAccessException {
+		Object result = null;
+		if (clazz.isPrimitive()) {
+			result = constructPrimitive(clazz);
+		} else if (clazz.isArray()) {
+			result = new Object[] {};
+		} else if (Modifier.isFinal(clazz.getModifiers())) {
+			result = clazz.newInstance();
+		} else {
+			result = new UsingClassMock().mock(clazz);
+		}
+		return result;
+	}
+
+	private static Object constructPrimitive(Class clazz) {
+		if (clazz == byte.class) {
+			return new Byte((byte) 0);
+		} else if (clazz == boolean.class) {
+			return Boolean.FALSE;
+		} else if (clazz == char.class) {
+			return new Character(' ');
+		} else if (clazz == double.class) {
+			return new Double(0);
+		} else if (clazz == float.class) {
+			return new Float(0);
+		} else if (clazz == int.class) {
+			return new Integer(0);
+		} else if (clazz == long.class) {
+			return new Long(0L);
+		} else if (clazz == short.class) {
+			return new Short((short) 0);
+		} else {
+			throw new IllegalArgumentException("Never heard of a primitive called " + clazz + " before. ");
+		}
+	}
+
 	private class ExpectationHandlerDelegate extends ExpectationHandler implements MethodInterceptor {
 		public Object intercept(Object thisProxy, Method method, Object[] args, MethodProxy superProxy) throws Throwable {
 			return this.invoke(thisProxy, method, args);


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to