Source Code Cross Referenced for MockMethod.java in  » Testing » Surrogate » net » sf » surrogate » core » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » Surrogate » net.sf.surrogate.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2005 Per S Hustad. All rights reserved.
002:         *
003:         * Redistribution and use in source and binary forms, with or without 
004:         * modification, are permitted provided that the following conditions are met:
005:         *
006:         *  o Redistributions of source code must retain the above copyright notice, 
007:         *    this list of conditions and the following disclaimer. 
008:         *    
009:         *  o Redistributions in binary form must reproduce the above copyright notice, 
010:         *    this list of conditions and the following disclaimer in the documentation 
011:         *    and/or other materials provided with the distribution. 
012:         *    
013:         *  o Neither the name of surrogate.sourceforge.net nor the names of 
014:         *    its contributors may be used to endorse or promote products derived 
015:         *    from this software without specific prior written permission. 
016:         *    
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
018:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
019:         * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
020:         * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
024:         * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
025:         * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
026:         * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
027:         * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         */
029:
030:        package net.sf.surrogate.core;
031:
032:        import java.lang.reflect.AccessibleObject;
033:        import java.lang.reflect.Constructor;
034:        import java.lang.reflect.Method;
035:
036:        import com.mockobjects.ExceptionalReturnValue;
037:        import com.mockobjects.ExpectationCounter;
038:        import com.mockobjects.ExpectationList;
039:        import com.mockobjects.ReturnValues;
040:
041:        /**
042:         * General mock class to mock a specific method. Useful to mock "final" methods
043:         * where it is impossible to override the actual class with a Mock
044:         * implementation.
045:         * <p>
046:         * Example:
047:         * <pre>
048:         *  SurrogateManager manager = SurrogateManager.getInstance();
049:         *  manager.reset();
050:         *  MockMethod mockTime = new MockMethod(java.lang.System.class,&quot;currentTimeMillis&quot;);
051:         *  manager.addMockMethod(mockTime);
052:         *  mockTime.addReturnValue(new Long(2000));
053:         *  mockTime.addReturnValue(new Long(4000));
054:         *  mockTime.setExpectedCalls(4);
055:         *  ...
056:         *  ...
057:         *  mockTime.verify();
058:         *  </pre>
059:         *  <p>
060:         *  Registers a mock method for the <code>java.lang.System.currentTimeMillis</code>
061:         *  method and specifies that the method should be called exactly four times,
062:         *  or else an error is generated. The first call returns "2000" and
063:         *  the next three calls return "4000"
064:         * 
065:         *  @see SurrogateManager#addMockMethod(MockMethod)
066:         *  
067:         *  @author Per S Hustad
068:         * 
069:         */
070:        public class MockMethod implements  SurrogateManager.MockExecutor {
071:
072:            private AccessibleObject method;
073:
074:            private ExpectationCounter myCalls;
075:
076:            private ReturnValues myReturnValues;
077:
078:            private ExpectationList[] myParameterValues;
079:
080:            private Class[] parameterTypes;
081:
082:            private boolean isVoid;
083:
084:            /**
085:             * Mocks a method. Useful if it has been impossible to generate a mock
086:             * object for a class, e.g. the class contains <code>final</code> methods
087:             * or we want to mock a <code>static</code> method.
088:             * <p>
089:             * Note that for methods to be substituted with their mock implementation,
090:             * there must have been defined a <code>pointcut</code> intercepting the
091:             * method call or method execution. Otherwise, the mock method will never be
092:             * called, even if it has been registered. 
093:             * See {@link net.sf.surrogate.core.SurrogateCalls} for 
094:             * pointcut definition details.
095:             * <p>
096:             * 
097:             * @param theClass
098:             *            the class containing the method to mock.
099:             * @param method
100:             *            name of the method to mock. Must exist in the class.
101:             * @param parameterTypes
102:             *            the formal parameters to the method. E.g. if the method is
103:             *            declared as
104:             *            <code>int foo(int count,Context ccx,Integer obj)</code> the
105:             *            formal parameters will be
106:             *            <code>{Integer.TYPE,Context.class,Integer.class}</code>
107:             * @throws NoSuchMethodException
108:             *             if the method cannot be found
109:             * @see SurrogateManager#addMockMethod(MockMethod)
110:             */
111:            public MockMethod(Class theClass, String method,
112:                    Class[] parameterTypes) throws NoSuchMethodException {
113:                Method m = theClass.getDeclaredMethod(method, parameterTypes);
114:                isVoid = (m.getReturnType() == Void.TYPE);
115:                init(m, m.getParameterTypes());
116:            }
117:
118:            /**
119:             * Mocks a method. This method is useful in the case where it has been
120:             * impossible to generate a mock object for a class, e.g. the class contains
121:             * <code>final</code> methods or we want to mock a <code>static</code>
122:             * method.
123:             * <p>
124:             * Note that for methods to be substituted with their mock implementation,
125:             * there must have been defined a <code>pointcut</code> intercepting the
126:             * method call or method execution. Otherwise, the mock method will never be
127:             * called, even if it has been registered. See {@link SurrogateCalls}for
128:             * pointcut definition details.
129:             * <p>
130:             * 
131:             * @param theClass
132:             *            the class containing the method to mock.
133:             * @param method
134:             *            name of the method to mock. Must exist in the class <b>and
135:             *            only one method with that name must exist </b>. If several
136:             *            overloaded methods exists with the same name, use
137:             *            {@link #MockMethod(Class,String,Class[])}
138:             * @throws NoSuchMethodException
139:             *             if the method cannot be found
140:             * @throws IllegalArgumentException
141:             *             if more than one method exists with the name.
142:             * @see #MockMethod(Class, String, Class[])
143:             * @see #MockMethod(Class, Class[])
144:             * @see SurrogateManager#addMockMethod(MockMethod)
145:             */
146:            public MockMethod(Class theClass, String method)
147:                    throws NoSuchMethodException {
148:                Method m[] = theClass.getDeclaredMethods();
149:                int index = -1;
150:                int count = 0;
151:                for (int i = 0; i < m.length; i++) {
152:                    if (m[i].getName().equals(method)) {
153:                        index = i;
154:                        count++;
155:                        if (count > 1) {
156:                            throw new IllegalArgumentException(
157:                                    "More than one method:"
158:                                            + theClass.getName() + "." + method);
159:                        }
160:                    }
161:                }
162:                if (index < 0) {
163:                    throw new NoSuchMethodException(theClass.getName() + "."
164:                            + method);
165:                }
166:                isVoid = (m[index].getReturnType() == Void.TYPE);
167:                init(m[index], m[index].getParameterTypes());
168:            }
169:
170:            /**
171:             * Mocks a constructor.
172:             * <p>
173:             * This method is useful when it has been impossible to generate a mock
174:             * object for a class, e.g. the class is final or the "real" constructor
175:             * makes some unwanted procssing.
176:             * <p>
177:             * Note that for constructors to be substituted with their mock
178:             * implementation, there must have been defined a <code>pointcut</code>
179:             * intercepting the constructor call or execution. Otherwise, the mock
180:             * method will never be called, even if it has been registered. See
181:             * {@link SurrogateCalls}for pointcut definition details.
182:             * <p>
183:             * Note, that for mock constructors, the corresponding <code>pointcut</code>
184:             * should be a <b>call </b> type pointcut if the corresponding
185:             * <code>MockMethod</code> is to return some values. If the
186:             * <code>pointcut</code> is "execution", the return values from the
187:             * MockMethod will disappear somewhere in the VM ....
188:             * 
189:             * @param theClass
190:             *            the class containing the constructor to mock.
191:             * @param parameterTypes
192:             *            the formal parameters to the constructor. E.g. if the
193:             *            constructor is declared as
194:             *            <code>Foo(int count,Context ccx,Integer obj)</code> the
195:             *            formal parameters will be
196:             *            <code>{Integer.TYPE,Context.class,Integer.class}</code>
197:             * @throws NoSuchMethodException
198:             *             if the constructor cannot be found
199:             * @see SurrogateManager#addMockMethod(MockMethod)
200:             */
201:            public MockMethod(Class theClass, Class[] parameterTypes)
202:                    throws NoSuchMethodException {
203:                Constructor c = theClass.getDeclaredConstructor(parameterTypes);
204:                isVoid = false;
205:                init(c, c.getParameterTypes());
206:            }
207:
208:            private void init(AccessibleObject accessible,
209:                    Class[] parameterTypes) {
210:                this .method = accessible;
211:                this .parameterTypes = parameterTypes;
212:                reset();
213:            }
214:
215:            /**
216:             * Resets the mock method counters, expectation values and stored actual
217:             * values.
218:             */
219:            public void reset() {
220:                myCalls = new ExpectationCounter("Mock" + method.toString());
221:                myReturnValues = new ReturnValues("Mock" + method.toString(),
222:                        true);
223:
224:                myParameterValues = new ExpectationList[parameterTypes.length];
225:                for (int i = 0; i < parameterTypes.length; i++) {
226:                    myParameterValues[i] = new ExpectationList(method
227:                            .toString()
228:                            + " arg" + i + " values");
229:                }
230:            }
231:
232:            /**
233:             * Sets the number of expected calls to this method. The
234:             * 
235:             * {@link #verify()} method verifies the calls. Note that if you don't call
236:             *        this method after a reset or creation, the verify method will not
237:             *        check the actual calls.
238:             * @param expectedCalls
239:             *            the number of expected calls.
240:             * @see #verify()
241:             */
242:            public void setExpectedCalls(int expectedCalls) {
243:                myCalls.setExpected(expectedCalls);
244:            }
245:
246:            /**
247:             * Sets up the next return value of the mock method. If the method is called
248:             * more times than the calls to this method, the last specified return value
249:             * is used.
250:             * 
251:             * @param o
252:             *            the next return value. Primitive types are specified with
253:             *            their corresponding Object representation, e.g. an "int"
254:             *            corresponds to "Integer".
255:             * @throws IllegalArgumentException
256:             *             if the underlying AccessibleObject is a method returning
257:             *             <code>void</code>
258:             * @see #addThrowableReturnValue(Throwable)
259:             */
260:            public void addReturnValue(Object o) {
261:                if (isVoid) {
262:                    throw new IllegalArgumentException(
263:                            "No return type may be specified for \"void\" method");
264:                }
265:                myReturnValues.add(o);
266:
267:            }
268:
269:            /**
270:             * Adds an errror to the list of return values.
271:             * 
272:             * @param arg
273:             *            the throwable to throw on the next call. The mock method will
274:             *            throw this throwable even if the actual method does not
275:             *            declare it ...
276:             * @see #addReturnValue(Object)
277:             */
278:            public void addThrowableReturnValue(Throwable arg) {
279:                myReturnValues.add(new ExceptionalReturnValue(arg));
280:            }
281:
282:            /**
283:             * Sets up the next excpected arguments for the method. The actual arguments
284:             * are verified against the expected arguments when the actual method call
285:             * is performed. If they mismatch, an Exception will be thrown.
286:             * 
287:             * @param args
288:             *            array of Object values. <b>NB: </b> must correspond to the
289:             *            formal parameter types of the method or else a runtime
290:             *            exception will be thrown. Primitive types should be
291:             *            encapsulated in their corresponding Object representation,
292:             *            e.g. int corresponds to Integer
293:             * @throws IllegalArgumentException
294:             *             if the number of aruments in <code>args</code> differs from
295:             *             the number of arguments in the underlying method or
296:             *             constructor.
297:             */
298:            public void addExpectedParameters(Object[] args) {
299:                if (args != null && args.length != myParameterValues.length) {
300:                    throw new IllegalArgumentException(method.toString()
301:                            + ": got wrong number of parameters");
302:                }
303:                for (int i = 0; i < args.length; i++) {
304:                    myParameterValues[i].addExpected(args[i]);
305:                }
306:            }
307:
308:            /**
309:             * Performs the actual method call. This method should normally not be
310:             * called from test harnesses. It is called from the Surrogate core
311:             * framework
312:             * 
313:             * @param args
314:             *            the aruments to the method. Will be compared to the expected
315:             *            values if such values have been specified.
316:             * @return the return value given in {@link #addReturnValue(Object)}unless
317:             *         the next return value has been set with the
318:             *         {@link #addThrowableReturnValue(Throwable)}call. In this case,
319:             *         an Exception is thrown
320:             * 
321:             * @throws Throwable
322:             *             if an exception has been set up in
323:             *             {@link #addThrowableReturnValue(Throwable)} or if the number of parameters in
324:             *             <code>args</code> does not match the number of parameters
325:             *             in the method signature
326:             */
327:            public Object execute(Object[] args) throws Throwable {
328:                myCalls.inc();
329:                if (args != null && args.length != myParameterValues.length) {
330:                    throw new RuntimeException(method.toString()
331:                            + ": got wrong number of parameters");
332:                }
333:                if (args != null) {
334:                    for (int i = 0; i < args.length; i++) {
335:                        myParameterValues[i].addActual(args[i]);
336:                    }
337:                }
338:                if (myReturnValues.isEmpty() && isVoid) {
339:                    return null;
340:                }
341:                Object nextReturnValue = myReturnValues.getNext();
342:                if (nextReturnValue instanceof  ExceptionalReturnValue) {
343:                    throw ((ExceptionalReturnValue) nextReturnValue)
344:                            .getException();
345:                }
346:                return nextReturnValue;
347:
348:            }
349:
350:            /**
351:             * Gets the java reflection method or constructor
352:             * 
353:             * @return the accessible object as specified in the constructor
354:             */
355:            /* package protected */
356:            AccessibleObject getAccessibleObject() {
357:                return method;
358:            }
359:
360:            /**
361:             * Verifies that the method has been called as many times as specified in
362:             * {@link #setExpectedCalls(int)}
363:             * 
364:             * @see #setExpectedCalls(int)
365:             */
366:            public void verify() {
367:                myCalls.verify();
368:            }
369:
370:            /**
371:             * Gets a textual representation of this MockMethod
372:             * 
373:             * @return the underlying method or constructor's <code>toString</code>
374:             */
375:            public String toString() {
376:                return method.toString();
377:            }
378:
379:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.