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: package net.sf.surrogate.core;
030:
031: import junit.framework.TestCase;
032:
033: /**
034: * Tests the SurrogateManager.
035: * <p>
036: * Note that this testCase will be woven by the test framwork so that it can
037: * test that its own classes are "mocked" ! Keep this in mind when trying to
038: * understand the code
039: *
040: * @author Per S Hustad
041: */
042: public class SurrogateManagerTestCase extends TestCase {
043:
044: public SurrogateManagerTestCase(String name) {
045: super (name);
046: }
047:
048: /**
049: * test the getMockObjectForInterface
050: */
051: public void testGetMockObject_ForInterface() throws Exception {
052: SurrogateManager mm = SurrogateManager.getInstance();
053: mm.reset();
054: InterfaceToMockImp mI = new InterfaceToMockImp();
055: mm.addMock(mI);
056: Object mRet = mm.getMockObject(InterfaceToMock.class);
057: assertEquals(mI, mRet);
058: mm.reset();
059: mRet = mm.getMockObject(InterfaceToMock.class);
060: assertNull(mRet);
061: }
062:
063: /**
064: * test the getMockObjectForInterface
065: */
066: public void testGetMockObject_ForClass() throws Exception {
067: SurrogateManager mm = SurrogateManager.getInstance();
068: mm.reset();
069: MockClassToMock mock = new MockClassToMock();
070: mm.addMock(mock);
071: Object mRet = mm.getMockObject(ClassToMock.class);
072: assertEquals(mock, mRet);
073: mm.reset();
074: mRet = mm.getMockObject(ClassToMock.class);
075: assertNull(mRet);
076: }
077:
078: /**
079: * Test basic AspectJ pointcut pcGetInterfaceOrClass interaction. In the
080: * AspectJ file, we have defined a pointcut intercepting the calls to
081: * "getInterfaceToMock"
082: */
083: public void testPcGetInterfaceOrClass() {
084: SurrogateManager mm = SurrogateManager.getInstance();
085: mm.reset();
086: mm.addMock(new MockInterfaceToMock());
087: InterfaceToMock it = (InterfaceToMock) new TestClass01()
088: .getInterfaceToMock();
089: assertEquals("MOCK", it.getSomething("test"));
090: }
091:
092: /**
093: * This method is to test the difference between "call" and "execution"
094: * pointcuts when the returned class is casted to another type. This method
095: * MUST NOT be adviced
096: *
097: * @return an ExtendedClassToMock
098: */
099: private ClassToMock getExtendedClassToMock_call() {
100: return new ExtendedClassToMock();
101:
102: }
103:
104: /**
105: * This method is to test the difference between "call" and "execution"
106: * pointcuts when the returned class is casted to another type. This method
107: * MUST be adviced
108: *
109: * @return an ExtendedClassToMock
110: */
111: private ClassToMock getExtendedClassToMock_execution() {
112: return new ExtendedClassToMock(); // AOP pointcut here !
113: }
114:
115: /**
116: * Test that if we register both a Mock Method and a mock object
117: * corresponding to a poinctut, the MockMethod takes precedence
118: *
119: * @throws Exception
120: * if unexpected failure
121: */
122: public void testSetMockMethodAndObject() throws Exception {
123: SurrogateManager mm = SurrogateManager.getInstance();
124: mm.reset();
125: // first register a mock object
126: MockInterfaceToMock mockInterfaceToMock = new MockInterfaceToMock();
127: mm.addMock(mockInterfaceToMock);
128: TestClass01 sub = new TestClass01();
129: assertEquals("MOCK", sub.getInterfaceToMock().getSomething(
130: "hello"));
131: // Then register a mockmethod and tell that method
132: // to return a different mock class
133: MockMethod mocktestCall01 = mm.addMockMethod(new MockMethod(
134: TestClass01.class, "getInterfaceToMock"));
135: mocktestCall01.setExpectedCalls(1);
136: mocktestCall01.addReturnValue(new InterfaceToMock() {
137: public String getSomething(String s) {
138: return "Setup by mockmethod";
139: }
140: });
141: assertEquals("Setup by mockmethod", sub.getInterfaceToMock()
142: .getSomething("hello"));
143: mocktestCall01.verify();
144: // Then, remove the mock method and verify that the class is returned
145: Object removedMethod = mm.removeMockMethod(mocktestCall01);
146: assertEquals(mocktestCall01, removedMethod);
147: assertEquals("MOCK", sub.getInterfaceToMock().getSomething(
148: "hello"));
149: // Then remove the class and verify that "real" is returned
150: Object removedMock = mm.removeMock(mockInterfaceToMock);
151: assertEquals(mockInterfaceToMock, removedMock);
152: assertEquals("REAL", sub.getInterfaceToMock().getSomething(
153: "hello"));
154:
155: }
156:
157: /**
158: * Verifies that the SurrogateManager returns mocks corresponding to the
159: * <b>signature </b> of the declared method in execution and call pointcuts.
160: * I.e. when casting the class to another class, we might get a
161: * ClassCastException
162: *
163: * @throws Exception
164: */
165: public void testClassCastException() throws Exception {
166: SurrogateManager mm = SurrogateManager.getInstance();
167: mm.reset();
168: MockClassToMock mockClassToMock = new MockClassToMock();
169: MockExtendedClassToMock mockExtendedClassToMock = new MockExtendedClassToMock();
170:
171: // Verify that we get no ClassCastException - no mocks
172: ExtendedClassToMock extendedClassToMock = (ExtendedClassToMock) getExtendedClassToMock_call(); // AOP
173: // advice
174: // here
175: // !
176: assertEquals("ExtendedClassToMock", extendedClassToMock.status);
177: mm.addMock(mockClassToMock);
178:
179: // Check that casting of classes in a "call" pointcut is invariant. In
180: // this
181: // case, since the funtion actually returns a ExtendedClassToMock but
182: // declares that
183: // it returns a ClassToMock, the returned object will be MockClassToMock
184: // but since we cast it to ExtendedClassToMock - we expect a
185: // ClassCastException
186: try {
187: extendedClassToMock = (ExtendedClassToMock) getExtendedClassToMock_call(); // AOP
188: // advice
189: // here
190: // !
191: fail("Expected ClassCastException");
192: } catch (ClassCastException cce) {
193: }
194:
195: ClassToMock classToMock = getExtendedClassToMock_call(); // AOP advice
196: // here !
197: assertEquals("MockClassToMock", classToMock.status);
198:
199: // Check that casting of classes in a "execution" pointcut is invariant
200: // As in the case above, the method declares that it returns a
201: // ClassToMock
202: try {
203: extendedClassToMock = (ExtendedClassToMock) getExtendedClassToMock_execution(); // AOP
204: // in
205: // method
206: // executing
207: fail("Expected ClassCastException");
208: } catch (ClassCastException cce) {
209: }
210:
211: classToMock = getExtendedClassToMock_execution(); // AOP in method
212: // executing
213: assertEquals("MockClassToMock", classToMock.status);
214:
215: }
216:
217: private static interface InterfaceToMock {
218:
219: public String getSomething(String s);
220: }
221:
222: private static class MockInterfaceToMock implements InterfaceToMock {
223:
224: public String getSomething(String s) {
225: return "MOCK";
226: }
227: }
228:
229: private static class InterfaceToMockImp implements InterfaceToMock {
230:
231: public String getSomething(String s) {
232: return "REAL";
233: }
234: }
235:
236: private static class ClassToMock {
237:
238: public String status;
239:
240: public ClassToMock() {
241: status = "ClassToMock";
242: }
243:
244: public String getSomething(String s) {
245: return s;
246: }
247: }
248:
249: private static class ExtendedClassToMock extends ClassToMock {
250:
251: public String status;
252:
253: public ExtendedClassToMock() {
254: status = "ExtendedClassToMock";
255: }
256:
257: public String getSomething(String s) {
258: return s;
259: }
260:
261: public void fooExtend() {
262: ;
263: }
264: }
265:
266: private static class MockClassToMock extends ClassToMock {
267:
268: public String getSomething(String s) {
269: return super .getSomething(s);
270: }
271:
272: public MockClassToMock() {
273: status = "MockClassToMock";
274: }
275:
276: public String getStatus() {
277: return status;
278: }
279: }
280:
281: private static class MockExtendedClassToMock extends
282: ExtendedClassToMock {
283:
284: public String getSomething(String s) {
285: return super .getSomething(s);
286: }
287:
288: public MockExtendedClassToMock() {
289: status = "MockExtendedClassToMock";
290: }
291:
292: public String getStatus() {
293: return status;
294: }
295: }
296:
297: private static class TestClass01 {
298:
299: //should be adviced in aspect
300: public String testCall01(String a, String b) {
301: return "OK";
302: }
303:
304: //should be adviced
305: public boolean isSomething() {
306: return true;
307: }
308:
309: // should be adviced
310: public boolean isSomething(String arg1) {
311: return true;
312: }
313:
314: // should be adviced
315: public InterfaceToMock getInterfaceToMock() {
316: return new InterfaceToMockImp();
317: }
318:
319: }
320:
321: }
|