Update of /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/dynamic In directory sc8-pr-cvs1:/tmp/cvs-serv25351/core/com/mockobjects/dynamic Modified Files: CallBag.java C.java CallCollection.java CallSequence.java Mock.java Added Files: Callable.java CallStub.java ReturnStub.java FullConstraintMatcher.java CallMatch.java ExpectedCall.java VoidStub.java CallableAddable.java DefaultCallFactory.java ConstraintMatcher.java OrderedMock.java AnyConstraintMatcher.java ThrowStub.java DynamicUtil.java CallFactory.java Removed Files: MockReturnCall.java AbstractMockCall.java MockThrowCall.java MethodMap.java MethodExpectation.java CallCounter.java MockVoidCall.java MockCall.java Log Message: Integration with branch DynamicMockExperiment. If you have problems - you can revert to Version 08. Index: CallBag.java =================================================================== RCS file: /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/dynamic/CallBag.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- CallBag.java 4 Apr 2003 11:13:31 -0000 1.1 +++ CallBag.java 18 May 2003 20:59:35 -0000 1.2 @@ -1,23 +1,85 @@ +/* + * Created on 04-Apr-2003 + */ package com.mockobjects.dynamic; -/** - * Represents a collection of calls for which the order in which they are called is not checked but the total number of times is. - */ +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; -public class CallBag extends CallCollection { - +public class CallBag extends CallCollection implements Callable, CallableAddable { + private List expectedCalls = new ArrayList(); + private List expectedMatches = new ArrayList(); + public CallBag() { - super(); } - - protected int findCallIndexAndCheckArguments(Object[] args,int callnumber) { - for (int i = 0; i < _expected_constraints.size(); i++) { - if (!hasBeenCalled(i) && checkArguments(i, args)) { - return i; + + public void reset() { + this.expectedCalls.clear(); + this.expectedMatches.clear(); + } + + public Object call(Mock mock, String methodName, Object[] args) + throws Throwable { + + Callable matchingCall = findMatchingCall(methodName, args, this.expectedCalls); + if(matchingCall == null) { + matchingCall = findMatchingCall(methodName, args, this.expectedMatches); + } + if(matchingCall == null) { + throw createUnexpectedCallError(methodName, args); + } + + return matchingCall.call(mock, methodName, args); + + } + + private Callable findMatchingCall(String methodName, Object[] args, List callList) { + for (Iterator call = callList.iterator(); call.hasNext();) { + Callable element = (Callable) call.next(); + + if (element.matches(methodName, args)) { + return element; } } - fail(errorMessage(args)); - return -1; + + return null; + } + + public String getDescription() { + if (this.expectedCalls.isEmpty()) { + return "no methods"; + } else { + StringBuffer buf = new StringBuffer(); + + buf.append("one of:\n"); + + for (Iterator i = this.expectedCalls.iterator(); i.hasNext();) { + buf.append(((Callable) i.next()).getDescription()); + buf.append("\n"); + } + + return buf.toString(); + } + } + + public boolean matches(String methodName, Object[] args) { + throw new Error("not implemented"); + } + + public void verify() { + for (Iterator call = this.expectedCalls.iterator(); call.hasNext();) { + Callable element = (Callable) call.next(); + element.verify(); + } + } + + public void addExpect(Callable call) { + this.expectedCalls.add(call); + } + + public void addMatch(Callable call) { + this.expectedMatches.add(call); } } Index: C.java =================================================================== RCS file: /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/dynamic/C.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- C.java 24 Nov 2002 10:59:29 -0000 1.1 +++ C.java 18 May 2003 20:59:35 -0000 1.2 @@ -19,8 +19,8 @@ public static final Constraint IS_ZERO = eq(new Integer(0)); public static final Constraint IS_NOT_ZERO = not(IS_ZERO); - public static final Constraint[] ANY_ARGS = MockVoidCall.ANY_ARGS; - + public static final ConstraintMatcher NO_ARGS = new FullConstraintMatcher(new Constraint[0]); + public static final ConstraintMatcher ANY_ARGS = new AnyConstraintMatcher(); public static Constraint same( Object o ) { return new IsSame(o); @@ -29,7 +29,15 @@ public static Constraint eq( Object o ) { return new IsEqual(o); } - + + public static ConstraintMatcher eq( Object arg0, Object arg1 ) { + return args(eq(arg0), eq(arg1)); + } + + public static ConstraintMatcher eq( Object arg0, Object arg1, Object arg2 ) { + return args(eq(arg0), eq(arg1), eq(arg2)); + } + public static Constraint eq( int n ) { return new IsEqual( new Integer(n) ); } @@ -89,23 +97,34 @@ public static Constraint isA( Class c ) { return new IsInstanceOf(c); } + + /* Helper methods for succinctly constructing Constraint arrays */ - public static Constraint[] args() { - return Mock.NO_ARGS; + public static ConstraintMatcher args() { + return NO_ARGS; } - public static Constraint[] args(Constraint p) { - return new Constraint[] {p}; + public static ConstraintMatcher args(Constraint p) { + return new FullConstraintMatcher(new Constraint[]{p}); } - public static Constraint[] args(Constraint p1, Constraint p2) { - return new Constraint[] {p1, p2}; + public static ConstraintMatcher args(Constraint p1, Constraint p2) { + return new FullConstraintMatcher(new Constraint[]{p1, p2}); } - public static Constraint[] args(Constraint p1, Constraint p2, Constraint p3) { - return new Constraint[] {p1, p2, p3}; + public static ConstraintMatcher args(Constraint p1, Constraint p2, Constraint p3) { + return new FullConstraintMatcher(new Constraint[]{p1, p2, p3}); } + + public static ConstraintMatcher anyArgs( int argCount) { + Constraint[] constraints = new Constraint[argCount]; + for (int i = 0; i < constraints.length; i++) { + constraints[i] = new IsAnything(); + } + + return new FullConstraintMatcher(constraints); + } } Index: CallCollection.java =================================================================== RCS file: /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/dynamic/CallCollection.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- CallCollection.java 4 Apr 2003 11:13:31 -0000 1.1 +++ CallCollection.java 18 May 2003 20:59:35 -0000 1.2 @@ -1,225 +1,19 @@ -/** Created on Oct 31, 2002 by npryce - * Copyright (c) B13media Ltd. - */ package com.mockobjects.dynamic; -import java.util.ArrayList; -import java.util.List; - -import com.mockobjects.Verifiable; -import com.mockobjects.constraint.*; -import com.mockobjects.util.AssertMo; - -/** A {@link MockCall} that expects a sequence of calls, checks their - * arguments and mocks their behaviour. - * A test will fail if too few or too many calls are made. - */ -public abstract class CallCollection extends AssertMo implements MockCall, Verifiable { - protected List _expected_calls = new ArrayList(); - protected List _expected_constraints = new ArrayList(); - public static final String EXPECTED_CALLS="expected calls were:"; - public static final String NO_EXPECTED_CALLS="no expected calls were set"; - public static final String CALLED="called already" ; - public static final String NOT_CALLED="not called"; - public static final String ARGS="\nreceived arguments were "; - - private int numcalls = 0; - - protected List _hasBeenCalled = new ArrayList(); - - public CallCollection() { - super(); - } - - public void expect(MockCall call, Constraint[] constraints) { - _expected_calls.add(call); - _expected_constraints.add(constraints); - _hasBeenCalled.add(Boolean.FALSE); - } - - /* The following were copy-and-pasted from Mock.java with minor editing. - * Is there any way to remove this duplication? - */ - - /** Expect a method call and return a result when it is called. - * - * @param args - * An array of {@link com.mockobjects.dynamic.Constraint}s that specify the - * epxected arguments of the method call. The length of the array defines - * the expected arity of the method call. - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - */ - public void expectAndReturn(Constraint[] args, Object result) { - expect(new MockReturnCall(args, result), args); - } - - /** Expect a method call and return a result when it is called. - * - * @param arg - * An single object that will be compared with predicate same() - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - */ - public void expectAndReturn(Object arg, Object result) { - expectAndReturn(C.args(C.eq(arg)), result); - } - - /** Expect a method call with no parameters and return a result when it is called. - * - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - */ - public void expectAndReturn(Object result) { - expectAndReturn(Mock.NO_ARGS, result); - } - - /** Expect a call to a method with a void return type. - * - * @param args - * An array of {@link com.mockobjects.dynamic.Constraint}s that specify the - * epxected arguments of the method call. The length of the array defines - * the expected arity of the method call. - */ - public void expectVoid(Constraint[] args) { - expect(new MockVoidCall(args), args); - } - - /** Expect a call to a method with a void return type. - * - * @param method - * The name of the method that will be called. - * @param arg - * An single object that will be compared with predicate eq() - */ - public void expectVoid(Object arg) { - expectVoid(C.args(C.eq(arg))); - } - - /** Expect a call to a method with a void return type and no parameters - */ - public void expectVoid() { - expectVoid(Mock.NO_ARGS); - } - - /** Expect a method call and throw an exception or error when it is called. - * - * @param args - * An array of {@link com.mockobjects.dynamic.Constraint}s that specify the - * epxected arguments of the method call. The length of the array defines - * the expected arity of the method call. - * @param exception - * The exception or error that will be thrown as a result of this call. - */ - public void expectAndThrow(Constraint[] args, Throwable exception) { - expect(new MockThrowCall(args, exception), args); - } - - /** Expect a method call and throw an exception or error when it is called. - * - * @param arg - * An single object that will be compared with predicate eq() - * @param exception - * The exception or error that will be thrown as a result of this call. - */ - public void expectAndThrow(Object arg, Throwable exception) { - expectAndThrow(C.args(C.eq(arg)), exception); - } - - /** Expect a method call with no parameters and throw an exception or error when it is called. - * - * @param exception - * The exception or error that will be thrown as a result of this call. - */ - public void expectAndThrow(Throwable exception) { - expectAndThrow(Mock.NO_ARGS, exception); - } - - public Object call(Object[] args) throws Throwable { - numcalls++; - assertTrue(errorMessage(args), numcalls <= _expected_calls.size()); - - int callIndex = findCallIndexAndCheckArguments(args,numcalls); - MockCall call = (MockCall) _expected_calls.get(callIndex); - _hasBeenCalled.add(callIndex, Boolean.TRUE); - return call.call(args); - } - abstract protected int findCallIndexAndCheckArguments(Object[] args,int callNumber); - - protected boolean checkArguments(int index, Object[] args) { - Constraint[] cons =(Constraint[]) _expected_constraints.get(index); - int cons_count = (cons == null) ? 0 : cons.length; - int arg_count = (args == null) ? 0 : args.length; - if (cons_count != arg_count) { - return false; - } - - for (int i = 0; i < arg_count; i++) { - if (!cons[i].eval(args[i])) { - return false; - } - } - return true; - } - - public void verify() { - assertTrue(errorMessage(null), _expected_calls.size() == numcalls); - } - - public String printConstraint(int i) { - if (i < 0 || i > (_expected_constraints.size() - 1)) { - return ""; - } - - Constraint[] cons = (Constraint[]) _expected_constraints.get(i); - return printArgsArray(cons); - } - - protected String printArgsArray(Object[] array) { - if (array.length == 0) { - return "[no args]"; - } - StringBuffer result = new StringBuffer("["); - for (int j = 0; j < array.length; j++) { - result.append(array[j].toString()); - result.append(','); - } - result.deleteCharAt(result.length() - 1); - result.append(']'); - return result.toString(); - } - - public String errorMessage(Object[] args) { - - StringBuffer result = new StringBuffer(EXPECTED_CALLS); - if (_expected_constraints.size() == 0) { - result = new StringBuffer(NO_EXPECTED_CALLS); - } - for (int i = 0; i < _expected_constraints.size(); i++) { - result.append('\n'); - result.append(printConstraint(i)); - - result.append(" :" + (hasBeenCalled(i) ? CALLED : NOT_CALLED)); - } - if (args != null) { - result.append( ARGS+ printArgsArray(args)); - } - - return result.toString(); - } - - protected boolean hasBeenCalled(int i) { - return ((Boolean) _hasBeenCalled.get(i)).booleanValue(); - } - - +import junit.framework.AssertionFailedError; +abstract public class CallCollection extends Object { + protected AssertionFailedError createUnexpectedCallError(String methodName, Object[] args) { + + StringBuffer buf = new StringBuffer(); + buf.append("Unexpected call: "); + buf.append(DynamicUtil.methodToString(methodName, args)); + buf.append("\n"); + buf.append("Expected "); + buf.append(getDescription()); + return new AssertionFailedError(buf.toString()); + } + abstract protected String getDescription(); } Index: CallSequence.java =================================================================== RCS file: /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/dynamic/CallSequence.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- CallSequence.java 4 Apr 2003 11:13:31 -0000 1.4 +++ CallSequence.java 18 May 2003 20:59:35 -0000 1.5 @@ -1,28 +1,73 @@ package com.mockobjects.dynamic; -/** - * @author chris - * - * Represents a collection of calls on the same method for which the order of the calls is important - */ -public class CallSequence extends CallCollection { +import java.util.ArrayList; +import java.util.Iterator; - /** - * Constructor for CallSequence. - */ - public CallSequence() { - super(); - } +import junit.framework.AssertionFailedError; + +public class CallSequence extends CallCollection implements Callable, CallableAddable { + + private ArrayList expectedCalls = new ArrayList(); + private CallBag matchedCalls = new CallBag(); + int callIndex = 0; - protected int findCallIndexAndCheckArguments(Object[] args,int callnumber) { - int callIndex = callnumber - 1; - if (! checkArguments(callIndex, args) ){ - fail(errorMessage(args)); + public void reset() + { + this.expectedCalls.clear(); + this.matchedCalls.reset(); + } + + public Object call(Mock mock, String methodName, Object[] args) throws Throwable { + if (expectedCalls.size() == 0) throw new AssertionFailedError("no methods defined on mock, received: " + DynamicUtil.methodToString(methodName, args)); + if (callIndex == expectedCalls.size()) throw new AssertionFailedError("mock called too many times, received: " + DynamicUtil.methodToString(methodName, args)); + + Callable nextCall = (Callable)expectedCalls.get(callIndex++); + if (nextCall.matches(methodName, args)) + return nextCall.call(mock, methodName, args); + + try { + return matchedCalls.call(mock, methodName, args); + } catch (AssertionFailedError ex) { + throw createUnexpectedCallError(methodName, args); } - return callIndex; } - + public String getDescription() { + if (expectedCalls.isEmpty()) { + return "no methods"; + } else { + StringBuffer buf = new StringBuffer(); + + buf.append("in sequence:\n"); + + int j=0; + for (Iterator i = expectedCalls.iterator(); i.hasNext();) { + buf.append(((Callable)i.next()).getDescription()); + if (j++==(callIndex-1)) buf.append(" <<< Next Expected Call"); + buf.append("\n"); + } + + return buf.toString(); + } + } + + public boolean matches(String methodName, Object[] args) { + throw new AssertionFailedError("matches() operation not supported in CallSequence"); + } + + public void addExpect(Callable call) { + expectedCalls.add(call); + } + + public void addMatch(Callable call) { + matchedCalls.addMatch(call); + } + public void verify() { + for (Iterator iter = expectedCalls.iterator(); iter.hasNext();) { + Callable callable = (Callable) iter.next(); + callable.verify(); + } + } } Index: Mock.java =================================================================== RCS file: /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/dynamic/Mock.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- Mock.java 24 Nov 2002 11:01:00 -0000 1.16 +++ Mock.java 18 May 2003 20:59:35 -0000 1.17 @@ -1,461 +1,276 @@ -/* Copyright (c) 2002 Nat Pryce. All rights reserved. - * - * Created on February 10, 2002, 11:06 PM - */ package com.mockobjects.dynamic; -import com.mockobjects.Verifiable; -import com.mockobjects.constraint.*; - -import junit.framework.Assert; - import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.*; - - -/** A convenient class for creating simple - * <a href="http://www.mockobjects.com">mock objects</a>. - */ -public class Mock - extends Assert - implements InvocationHandler, Verifiable -{ - public static final Object VOID = new Object(); - - /** A convenient constant for defining expectations for methods that - * have no methods. - */ - public static final Constraint[] NO_ARGS = new Constraint[0]; - - - private Class[] _proxy_classes; - private Object _proxy; - private MethodMap methods = new MethodMap(); - private boolean _strict = false; - - private Map _default_results = new HashMap(); +import junit.framework.AssertionFailedError; - /** Creates a new Mock object that mocks the behaviour of - * a single interface. - */ - public Mock( Class interface_to_mock ) { - this( new Class[]{interface_to_mock} ); - } - - /** Creates a new Mock object that mocks the behaviour of - * two interfaces. - */ - public Mock( Class interface1, Class interface2 ) { - this( new Class[]{ interface1, interface2 } ); - } - - /** Creates a new Mock object that mocks the behaviour of - * three interfaces. - */ - public Mock( Class interface1, Class interface2, Class interface3 ) { - this( new Class[] { interface1, interface2, interface3 } ); - } - - /** Creates a new Mock object that mocks the behaviour of - * four interfaces. - */ - public Mock( Class interface1, Class interface2, - Class interface3, Class interface4 ) - { - this( new Class[] { interface1, interface2, interface3, interface4 } ); - } - - /** Creates a new Mock object that mocks the behaviour of - * any number of interfaces. - */ - public Mock( Class[] interfaces_to_mock ) { - _proxy_classes = (Class[])interfaces_to_mock.clone(); - _proxy = createInterface( interfaces_to_mock ); - - setupDefaultResult( byte.class, new Byte((byte)0) ); - setupDefaultResult( short.class, new Short((short)0) ); - setupDefaultResult( int.class, new Integer(0) ); - setupDefaultResult( long.class, new Long(0L) ); - setupDefaultResult( float.class, new Float(0.0f) ); - setupDefaultResult( double.class, new Double(0.0d) ); - setupDefaultResult( boolean.class, Boolean.FALSE ); - setupDefaultResult( char.class, new Character('\0') ); - setupDefaultResult( String.class, "" ); - } - - /** Returns an object that can be cast to any of the interfaces passed - * to this Mock's constructor. This Mock will mock the behaviour of - * calls to the proxy. - */ - public Object proxy() { - return _proxy; - } - - /** Is the mock in strict mode? In strict mode the mock will throw - * {@link junit.framework.AssertionFailedError} exceptions when - * unexpected method calls are made. Otherwise, the mock ignore - * the call or return default arguments. - */ - public boolean isStrict() { - return _strict; - } - - public void setStrict( boolean strict ) { - _strict = strict; - } - - /** Mock the behaviour of a method without requiring that the method - * actually be called. Note: the ExpectedCall may check the arguments - * of the call but should usually not do so. - * - * @param call - * The call to be mocked. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void setup( String method_name, MockCall call ) { - checkMethodName( method_name ); - methods.setupCall( method_name, call ); - } - - /** Set up calls to <var>method</var> to return <var>result</var>, - * but do not define any expectations upon arguments to those calls. - * Arguments of calls to <var>method</var> will be ignored. - * - * @param method_name - * The name of the method that will be called. - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void setupResult( String method_name, Object result ) { - setup( method_name, new MockReturnCall( result ) ); - } - - /** Set up calls to <var>method</var> to throw <var>exception</var>, - * but do not define any expectations upon arguments to those calls. - * Arguments of calls to <var>method</var> will be ignored. - * - * @param method_name - * The name of the method that will be called. - * @param exception - * The exception or error that will be thrown as a result of this call. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void setupThrow( String method_name, Throwable exception ) { - setup( method_name, new MockThrowCall( exception ) ); - } - - /** Set up the value returned by methods that have the given result - * type, if no result or exception has been explicitly defined for - * the called method by {@link #setupResult}, {@link #setupThrow}, - * {@link #expectReturn} or {@link #expectThrow}. - * - * @param result_type - * The result type of methods to be mocked. - * @param result_value - * The default value returned by mocked methods that return values - * of type <var>result_type</var>. - */ - public void setupDefaultResult( Class result_type, Object result_value ) { - _default_results.put( result_type, result_value ); - } - - /** Expect a method call and mock the behaviour of that call. - * - * @param call - * An object describing the expected call and mocking its behaviour. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expect( String method_name, MockCall call ) { - checkMethodName( method_name ); - methods.expectCall( method_name, call ); - } - - /** Expect a method call and return a result when it is called. - * - * @param method - * The name of the method that will be called. - * @param args - * An array of {@link com.mockobjects.dynamic.Constraint}s that specify the - * epxected arguments of the method call. The length of the array defines - * the expected arity of the method call. - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectAndReturn( String method, Constraint[] args, Object result ) { - expect( method, new MockReturnCall( args, result ) ); - } - - /** Expect a method call and return a result when it is called. - * - * @param method - * The name of the method that will be called. - * @param arg - * An single object that will be compared with predicate eq() - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectAndReturn( String method, Object arg, Object result ) { - expectAndReturn( method, C.args(C.eq(arg) ), result); - } - - /** Expect a method call with no parameters and return a result when it is called. - * - * @param method - * The name of the method that will be called. - * @param result - * The result that will be returned from this call. Primitive types - * must be wrapped in the equivalent Java object, and will be unwrapped - * before being returned to the caller of the method. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectAndReturn( String method, Object result ) { - expectAndReturn( method, NO_ARGS, result ); - } - - /** - * Expect a call to a method with a void return type. - * - * @param method - * The name of the method that will be called. - * @param args - * An array of {@link com.mockobjects.dynamic.Constraint}s that specify the - * epxected arguments of the method call. The length of the array defines - * the expected arity of the method call. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectVoid( String method, Constraint[] args ) { - expect( method, new MockVoidCall( args ) ); - } - - /** - * Expect a call to a method with a void return type. - * - * @param method - * The name of the method that will be called. - * @param arg - * An single object that will be compared with predicate eq() - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectVoid(String method, Object arg) { - expectVoid( method, C.args(C.eq(arg)) ); - } - - /** - * Expect a call to a method with a void return type and no parameters - * - * @param method - * The name of the method that will be called. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectVoid(String method) { - expectVoid( method, NO_ARGS ); - } - - /** Expect a method call and throw an exception or error when it is called. - * - * @param method - * The name of the method that will be called. - * @param args - * An array of {@link com.mockobjects.dynamic.Constraint}s that specify the - * epxected arguments of the method call. The length of the array defines - * the expected arity of the method call. - * @param exception - * The exception or error that will be thrown as a result of this call. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectAndThrow( String method, Constraint[] args, Throwable exception ) { - expect( method, new MockThrowCall( args, exception ) ); - } - - /** Expect a method call and throw an exception or error when it is called. - * - * @param method - * The name of the method that will be called. - * @param arg - * An single object that will be compared with predicate eq() - * @param exception - * The exception or error that will be thrown as a result of this call. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectAndThrow( String method, Object arg, Throwable exception ) { - expectAndThrow( method, C.args(C.eq(arg)), exception ); - } - - /** Expect a method call with no parameters and throw an exception or error when it is called. - * - * @param method - * The name of the method that will be called. - * @param exception - * The exception or error that will be thrown as a result of this call. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectAndThrow( String method, Throwable exception ) { - expectAndThrow( method, NO_ARGS, exception ); - } - - /** Expect a method not to be called. - * An {@link junit.framework.AssertionFailedError} will be thrown if - * the method is called. - * - * @param methodName - * The name of the method that will not be called. - * @throws junit.framework.AssertionFailedError - * The method name is not the name of a method mocked by this - * Mock object. - */ - public void expectNotCalled( String method_name ) { - checkMethodName( method_name ); - methods.expectNotCalled(method_name); - } - - /** Define an order between two calls. The method named - * <var>subsequent_method</var> <em>must</em> be called after - * the method namd <var>preceding_method</var>, otherwise an - * {@link junit.framework.AssertionFailedError} will be thrown - * when <var>subsequent_method</var> is called. - * - * @throws junit.framework.AssertionFailedError - * Either method name is not the name of a method mocked by this - * Mock object. - */ - public void order( String preceding_method, String subsequent_method ) { - checkMethodName( preceding_method ); - checkMethodName( subsequent_method ); - methods.order( preceding_method, subsequent_method ); - } - - - /** - * @see java.lang.Object#equals(java.lang.Object) - * This version will unpack the inovaction handler if the - * other object is a proxy. - */ - public boolean equals(Object obj) - { - try { - return equals(Proxy.getInvocationHandler(obj)); - } - catch (IllegalArgumentException notAProxy) { - return super.equals(obj); - } - } - - /** Called by the {@link java.lang.reflect.Proxy} to mock the behaviour of an - * invoked method and check expectations. - */ - public Object invoke( Object obj, Method method, Object[] args ) - throws Throwable - { - MethodExpectation expectation = methods.startCall(method.getName()); - try { - return getMatchingMethod(method).invoke( this, args ); - } - catch( NoSuchMethodException ex ) { - return mockCall( expectation, method, args ); - } - } - - protected Object mockCall( Method method, Object[] args ) - throws Throwable - { - return mockCall(methods.startCall(method.getName()), method, args); - } - - protected Object mockCall( MethodExpectation expectation, - Method method, - Object[] args ) - throws Throwable - { - if( expectation.canBeCalled() ) { - return expectation.callAndCheckResult( method, args ); - } else { - assertTrue( "unexpected call to "+method.getName(), !_strict ); - return defaultResult( method.getReturnType() ); - } - } - - - private Method getMatchingMethod(Method method) - throws NoSuchMethodException - { - return getClass().getMethod( method.getName(), method.getParameterTypes() ); - } - - private Object defaultResult(Class return_type) { - return _default_results.get(return_type); - } - - /** - * Fails if not all the expected calls have been made to this mock object. - * @throws junit.framework.AssertionFailedError - * Not all expected calls were made to this mock object. - */ - public void verify() { - methods.verify(); - } +import com.mockobjects.Verifiable; +import com.mockobjects.constraint.Constraint; - private Object createInterface( Class[] interface_classes ) { - return Proxy.newProxyInstance( getClass().getClassLoader(), - interface_classes, - this ); - } - - private void checkMethodName( String method_name ) { - for( int i = 0; i < _proxy_classes.length; i++ ) { - if( hasMethod( _proxy_classes[i], method_name ) ) { - return; - } - } - - fail("method " + method_name + - " is not defined by any of the mocked interfaces" ); - } - - private boolean hasMethod( Class c, String method_name ) { - Method[] methods = c.getMethods(); - for( int i = 0; i < methods.length; i++ ) { - if( methods[i].getName().equals(method_name) ) { - return true; - } - } - return false; - } +public class Mock implements InvocationHandler,Verifiable { + private String name; + private Object proxy; + private CallFactory callFactory; + private CallableAddable callSequence; + + public Mock(CallFactory callFactory, CallableAddable callableAddable, Class mockedClass, String name) { + this.name = name; + this.callFactory = callFactory; + this.callSequence = callableAddable; + this.proxy = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { mockedClass }, this); + } + + public Mock(Class mockedClass, String nonDefaultName) { + this(new DefaultCallFactory(), new CallBag(), mockedClass, nonDefaultName); + } + + public Mock(Class mockedClass) { + this(mockedClass, mockNameFromClass(mockedClass)); + } + + public void reset() { + this.callSequence.reset(); + } + + public static String mockNameFromClass(Class c) { + return "mock" + className(c); + } + + public static String className(Class c) { + String name = c.getName(); + int dotIndex = name.lastIndexOf('.'); + + if (dotIndex >= 0) { + return name.substring(dotIndex + 1); + } else { + return name; + } + } + + private ConstraintMatcher createConstraintMatcher(Object constraintArg) { + // Can't overload this method as callee had an Object parameter, and java + // doesn't do a secondary dispatch on the true underlying type + + if(constraintArg instanceof Constraint[]) { + // to support possible legacy usage of new Contraint[] {...} + return new FullConstraintMatcher((Constraint[])constraintArg); + } else if(constraintArg instanceof Constraint) { + // to support usage of C.lt(5) type constraints + return C.args((Constraint)constraintArg); + } else { + // normal usage of the overloaded expect/match object parameter + return C.args(C.eq(constraintArg)); + } + } + + public String getMockName() { + return this.name; + } + + public String toString() { + return this.name; + } + + public Object proxy() { + return this.proxy; + } + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + try { + if(checkingProxyEquality(method, args)) { + return new Boolean(args[0] == this.proxy); + } else if(gettingMockName(method, args)) { + return this.getMockName(); + } else { + Object result = callSequence.call(this, method.getName(), ((args == null) ? new Object[0] : args)); + return result; + } + } catch (AssertionFailedError ex) { + throw new AssertionFailedError(name + ": " + ex.getMessage()); + } + } + + private boolean checkingProxyEquality(Method method, Object[] args) { + return (method.getName().equals("equals")) && (args.length == 1) && (Proxy.isProxyClass(args[0].getClass())); + } + + private boolean gettingMockName(Method method, Object[] args) { + return (method.getName().equals("getMockName")) && (args.length == 0); + } + + public void verify() { + try { + callSequence.verify(); + } catch (AssertionFailedError ex) { + throw new AssertionFailedError(name + ": " + ex.getMessage()); + } + } + + public void expect(String methodName) { + expect(methodName, C.NO_ARGS); + } + + public void expect(String methodName, Object singleEqualArg) { + expect(methodName, createConstraintMatcher(singleEqualArg)); + } + + public void expect(String methodName, ConstraintMatcher args) { + callSequence.addExpect(callFactory.createExpectedCall(callFactory.createCallMatch(methodName, args, callFactory.createVoidStub()))); + } + + public void expectAndReturn(String methodName, Object result) { + this.expectAndReturn(methodName, C.NO_ARGS, result); + } + + public void expectAndReturn(String methodName, boolean result) { + this.expectAndReturn(methodName, new Boolean(result)); + } + + public void expectAndReturn(String methodName, int result) { + this.expectAndReturn(methodName, new Integer(result)); + } + + public void expectAndReturn(String methodName, Object singleEqualArg, Object result) { + this.expectAndReturn(methodName, createConstraintMatcher(singleEqualArg), result); + } + + public void expectAndReturn(String methodName, Object singleEqualArg, boolean result) { + this.expectAndReturn(methodName, singleEqualArg, new Boolean(result)); + } + + public void expectAndReturn(String methodName, Object singleEqualArg, int result) { + this.expectAndReturn(methodName, singleEqualArg, new Integer(result)); + } + + public void expectAndReturn(String methodName, ConstraintMatcher args, Object result) { + callSequence.addExpect(callFactory.createExpectedCall(callFactory.createCallMatch(methodName, args, callFactory.createReturnStub(result)))); + } + + public void expectAndReturn(String methodName, ConstraintMatcher args, boolean result) { + this.expectAndReturn(methodName, args, new Boolean(result)); + } + + public void expectAndReturn(String methodName, ConstraintMatcher args, int result) { + this.expectAndReturn(methodName, args, new Integer(result)); + } + + public void expectAndThrow(String methodName, Throwable exception) { + this.expectAndThrow(methodName, C.NO_ARGS, exception); + } + + public void expectAndThrow(String methodName, Object singleEqualArg, Throwable exception) { + this.expectAndThrow(methodName, createConstraintMatcher(singleEqualArg), exception); + } + + public void expectAndThrow(String methodName, ConstraintMatcher args, Throwable exception) { + callSequence.addExpect(callFactory.createExpectedCall(callFactory.createCallMatch(methodName, args, callFactory.createThrowStub(exception)))); + } + + public void matchAndReturn(String methodName, Object result) { + this.matchAndReturn(methodName, C.NO_ARGS, result); + } + + public void matchAndReturn(String methodName, boolean result) { + this.matchAndReturn(methodName, new Boolean(result)); + } + + public void matchAndReturn(String methodName, int result) { + this.matchAndReturn(methodName, new Integer(result)); + } + + public void matchAndReturn(String methodName, Object singleEqualArg, Object result) { + this.matchAndReturn(methodName, createConstraintMatcher(singleEqualArg), result); + } + + public void matchAndReturn(String methodName, boolean singleEqualArg, Object result) { + this.matchAndReturn(methodName, new Boolean(singleEqualArg), result); + } + + public void matchAndReturn(String methodName, int singleEqualArg, Object result) { + this.matchAndReturn(methodName, new Integer(singleEqualArg), result); + } + + public void matchAndReturn(String methodName, Object singleEqualArg, boolean result) { + this.matchAndReturn(methodName, singleEqualArg, new Boolean(result)); + } + + public void matchAndReturn(String methodName, Object singleEqualArg, int result) { + this.matchAndReturn(methodName, singleEqualArg, new Integer(result)); + } + + public void matchAndReturn(String methodName, ConstraintMatcher args, Object result) { + callSequence.addMatch(callFactory.createCallMatch(methodName, args, callFactory.createReturnStub(result))); + } + + public void matchAndReturn(String methodName, ConstraintMatcher args, boolean result) { + this.matchAndReturn(methodName, args, new Boolean(result)); + } + + public void matchAndReturn(String methodName, ConstraintMatcher args, int result) { + this.matchAndReturn(methodName, args, new Integer(result)); + } + + public void matchAndThrow(String methodName, Throwable throwable) { + this.matchAndThrow(methodName, C.NO_ARGS, throwable); + } + + public void matchAndThrow(String methodName, Object singleEqualArg, Throwable throwable) { + this.matchAndThrow(methodName, createConstraintMatcher(singleEqualArg), throwable); + } + + public void matchAndThrow(String methodName, boolean singleEqualArg, Throwable throwable) { + this.matchAndThrow(methodName,new Boolean(singleEqualArg), throwable); + } + + public void matchAndThrow(String methodName, int singleEqualArg, Throwable throwable) { + this.matchAndThrow(methodName,new Integer(singleEqualArg), throwable); + } + + public void matchAndThrow(String methodName, ConstraintMatcher args, Throwable throwable) { + callSequence.addMatch(callFactory.createCallMatch(methodName, args, callFactory.createThrowStub(throwable))); + } + + /** @deprecated @see OrderedMock + */ + public void expect(String methodName, CallSequence deprecated) { + throw new AssertionFailedError("method is deprecated! Use: new OrderedMock() instead..."); + } + + /** @deprecated @see OrderedMock + */ + public void expectAndReturn(String methodName, CallSequence deprecated, Object result) { + throw new AssertionFailedError("method is deprecated! Use: new OrderedMock() instead..."); + } + + /** @deprecated @see OrderedMock + */ + public void expectAndThrow(String methodName, CallSequence deprecated, Throwable throwable) { + throw new AssertionFailedError("method is deprecated! Use: new OrderedMock() instead..."); + } + + /** @deprecated @see expect + */ + public void expectVoid(String methodName, ConstraintMatcher args) { + this.expect(methodName, args); + } + + /** @deprecated @see expect + */ + public void expectVoid(String methodName, Object equalArg) { + this.expect(methodName,equalArg); + } + + /** @deprecated @see expect + */ + public void expectVoid(String methodName) { + this.expect(methodName); + } + + /** @deprecated Not required, as if methodName is called, you will get a an exception + */ + public void expectNotCalled(String methodName) { + } } --- MockReturnCall.java DELETED --- --- AbstractMockCall.java DELETED --- --- MockThrowCall.java DELETED --- --- MethodMap.java DELETED --- --- MethodExpectation.java DELETED --- --- CallCounter.java DELETED --- --- MockVoidCall.java DELETED --- --- MockCall.java DELETED --- |