View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit;
7   
8   import static org.junit.jupiter.api.Assertions.assertArrayEquals;
9   import static org.junit.jupiter.api.Assertions.assertEquals;
10  import static org.junit.jupiter.api.Assertions.assertFalse;
11  import static org.junit.jupiter.api.Assertions.assertNull;
12  import static org.junit.jupiter.api.Assertions.assertSame;
13  import static org.junit.jupiter.api.Assertions.assertThrows;
14  import static org.junit.jupiter.api.Assertions.assertTrue;
15  import static org.junit.jupiter.api.Assertions.fail;
16  
17  import java.util.ArrayList;
18  import java.util.Collection;
19  import java.util.List;
20  
21  import mockit.integration.junit5.ExpectedException;
22  import mockit.integration.junit5.JMockitExtension;
23  import mockit.internal.expectations.invocation.MissingInvocation;
24  
25  import org.junit.jupiter.api.Assertions;
26  import org.junit.jupiter.api.Test;
27  import org.junit.jupiter.api.extension.ExtendWith;
28  
29  /**
30   * The Class DelegateTest.
31   */
32  @ExtendWith(JMockitExtension.class)
33  @SuppressWarnings("unused")
34  class DelegateTest {
35  
36      /**
37       * The Class Collaborator.
38       */
39      static class Collaborator {
40  
41          /**
42           * Instantiates a new collaborator.
43           */
44          Collaborator() {
45          }
46  
47          /**
48           * Instantiates a new collaborator.
49           *
50           * @param i
51           *            the i
52           */
53          Collaborator(int i) {
54          }
55  
56          /**
57           * Gets the value.
58           *
59           * @return the value
60           */
61          int getValue() {
62              return -1;
63          }
64  
65          /**
66           * Do something.
67           *
68           * @param b
69           *            the b
70           * @param i
71           *            the i
72           * @param s
73           *            the s
74           *
75           * @return the string
76           */
77          String doSomething(boolean b, int[] i, String s) {
78              return s + b + i[0];
79          }
80  
81          /**
82           * Static method.
83           *
84           * @return true, if successful
85           */
86          static boolean staticMethod() {
87              return true;
88          }
89  
90          /**
91           * Static method.
92           *
93           * @param i
94           *            the i
95           *
96           * @return true, if successful
97           */
98          static boolean staticMethod(int i) {
99              return i > 0;
100         }
101 
102         /**
103          * Native method.
104          *
105          * @param b
106          *            the b
107          *
108          * @return the long
109          */
110         protected native long nativeMethod(boolean b);
111 
112         /**
113          * Native method returning an array of A primitive type.
114          *
115          * @return the int[]
116          */
117         public native int[] nativeMethodReturningAnArrayOfAPrimitiveType();
118 
119         /**
120          * Native method returning an array of A reference type.
121          *
122          * @return the foo[]
123          */
124         public native Foo[] nativeMethodReturningAnArrayOfAReferenceType();
125 
126         /**
127          * Native method returning A two dimensional array.
128          *
129          * @return the string[][]
130          */
131         public native String[][] nativeMethodReturningATwoDimensionalArray();
132 
133         /**
134          * Final method.
135          *
136          * @return the char
137          */
138         final char finalMethod() {
139             return 's';
140         }
141 
142         /**
143          * Adds the elements.
144          *
145          * @param elements
146          *            the elements
147          */
148         void addElements(List<String> elements) {
149             elements.add("one element");
150         }
151 
152         /**
153          * Gets the foo.
154          *
155          * @return the foo
156          */
157         Foo getFoo() {
158             return null;
159         }
160 
161         /**
162          * Gets the array.
163          *
164          * @return the array
165          */
166         byte[] getArray() {
167             return null;
168         }
169     }
170 
171     /**
172      * The Class Foo.
173      */
174     static final class Foo {
175         /**
176          * Do something.
177          *
178          * @return the int
179          */
180         int doSomething() {
181             return 1;
182         }
183     }
184 
185     /**
186      * Result from delegate.
187      *
188      * @param collaborator
189      *            the collaborator
190      */
191     @Test
192     void resultFromDelegate(@Mocked final Collaborator collaborator) {
193         final boolean bExpected = true;
194         final int[] iExpected = {};
195         final String sExpected = "test";
196 
197         new Expectations() {
198             {
199                 collaborator.getValue();
200                 result = new Delegate<Object>() {
201                     int getValue() {
202                         return 2;
203                     }
204                 };
205 
206                 collaborator.doSomething(bExpected, iExpected, sExpected);
207                 result = new Delegate<Object>() {
208                     String doSomething(boolean b, int[] i, String s) {
209                         assertEquals(bExpected, b);
210                         assertArrayEquals(iExpected, i);
211                         assertEquals(sExpected, s);
212                         return "";
213                     }
214                 };
215             }
216         };
217 
218         assertEquals(2, collaborator.getValue());
219         assertEquals("", collaborator.doSomething(bExpected, iExpected, sExpected));
220     }
221 
222     /**
223      * Consecutive results through delegates having different values.
224      *
225      * @param mock
226      *            the mock
227      */
228     @Test
229     void consecutiveResultsThroughDelegatesHavingDifferentValues(@Mocked final Collaborator mock) {
230         new Expectations() {
231             {
232                 mock.getValue();
233                 result = new Delegate<Object>() {
234                     int getValue() {
235                         return 1;
236                     }
237                 };
238                 result = new Delegate<Object>() {
239                     int getValue() {
240                         return 2;
241                     }
242                 };
243             }
244         };
245 
246         Collaborator collaborator = new Collaborator();
247         assertEquals(1, collaborator.getValue());
248         assertEquals(2, collaborator.getValue());
249     }
250 
251     /**
252      * Consecutive return values through delegates using single returns with varargs.
253      *
254      * @param collaborator
255      *            the collaborator
256      */
257     @Test
258     void consecutiveReturnValuesThroughDelegatesUsingSingleReturnsWithVarargs(@Mocked final Collaborator collaborator) {
259         final int[] array = { 1, 2 };
260 
261         new Expectations() {
262             {
263                 collaborator.doSomething(true, array, "");
264                 returns(new Delegate<Object>() {
265                     String execute(boolean b, int[] i, String s) {
266                         assertEquals(1, i[0]);
267                         return "a";
268                     }
269                 }, new Delegate<Object>() {
270                     String execute(boolean b, int[] i, String s) {
271                         assertEquals(2, i[0]);
272                         return "b";
273                     }
274                 });
275             }
276         };
277 
278         assertEquals("a", collaborator.doSomething(true, array, ""));
279 
280         array[0] = 2;
281         assertEquals("b", collaborator.doSomething(true, array, ""));
282     }
283 
284     /**
285      * Result with multiple return values through single delegate.
286      *
287      * @param collaborator
288      *            the collaborator
289      */
290     @Test
291     void resultWithMultipleReturnValuesThroughSingleDelegate(@Mocked final Collaborator collaborator) {
292         new Expectations() {
293             {
294                 collaborator.getValue();
295                 result = new Delegate<Object>() {
296                     int i = 1;
297 
298                     int getValue() {
299                         return i++;
300                     }
301                 };
302             }
303         };
304 
305         assertEquals(1, collaborator.getValue());
306         assertEquals(2, collaborator.getValue());
307         assertEquals(3, collaborator.getValue());
308     }
309 
310     /**
311      * Constructor delegate with single method.
312      *
313      * @param mock
314      *            the mock
315      */
316     @Test
317     void constructorDelegateWithSingleMethod(@Mocked Collaborator mock) {
318         final ConstructorDelegate delegate = new ConstructorDelegate();
319 
320         new Expectations() {
321             {
322                 new Collaborator(anyInt);
323                 result = delegate;
324             }
325         };
326 
327         new Collaborator(4);
328 
329         assertTrue(delegate.capturedArgument > 0);
330     }
331 
332     /**
333      * The Class ConstructorDelegate.
334      */
335     static class ConstructorDelegate implements Delegate<Void> {
336 
337         /** The captured argument. */
338         int capturedArgument;
339 
340         /**
341          * Delegate.
342          *
343          * @param i
344          *            the i
345          */
346         void delegate(int i) {
347             capturedArgument = i;
348         }
349     }
350 
351     /**
352      * Constructor delegate with multiple methods.
353      *
354      * @param mock
355      *            the mock
356      */
357     @Test
358     void constructorDelegateWithMultipleMethods(@Mocked Collaborator mock) {
359         new Expectations() {
360             {
361                 new Collaborator(anyInt);
362                 result = new Delegate<Object>() {
363                     void init(int i) {
364                         if (i < 0)
365                             throw new IllegalArgumentException();
366                     }
367 
368                     private void anotherMethod() {
369                     }
370                 };
371             }
372         };
373 
374         new Collaborator(123);
375 
376         try {
377             new Collaborator(-123);
378             fail();
379         } catch (IllegalArgumentException ignore) {
380         }
381     }
382 
383     /**
384      * Attempt to use constructor delegate with private methods only.
385      *
386      * @param mock
387      *            the mock
388      */
389     @Test
390     @ExpectedException(value = MissingInvocation.class)
391     void attemptToUseConstructorDelegateWithPrivateMethodsOnly(@Mocked Collaborator mock) {
392         Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
393             new Expectations() {
394                 {
395                     new Collaborator();
396                     result = new Delegate<Object>() {
397                         private void delegate() {
398                         }
399 
400                         private void anotherMethod() {
401                         }
402                     };
403                 }
404             };
405         });
406         Assertions.assertEquals("No non-private instance method found", exception.getMessage());
407     }
408 
409     /**
410      * Delegate for static method.
411      *
412      * @param unused
413      *            the unused
414      */
415     @Test
416     void delegateForStaticMethod(@Mocked Collaborator unused) {
417         new Expectations() {
418             {
419                 Collaborator.staticMethod();
420                 result = new Delegate<Object>() {
421                     boolean staticMethod() {
422                         return false;
423                     }
424                 };
425             }
426         };
427 
428         assertFalse(Collaborator.staticMethod());
429     }
430 
431     /**
432      * Delegate with static method.
433      *
434      * @param mock
435      *            the mock
436      */
437     @Test
438     void delegateWithStaticMethod(@Mocked Collaborator mock) {
439         new Expectations() {
440             {
441                 Collaborator.staticMethod(anyInt);
442                 result = StaticDelegate.create();
443             }
444         };
445 
446         assertTrue(Collaborator.staticMethod(34));
447     }
448 
449     /**
450      * The Class StaticDelegate.
451      */
452     static final class StaticDelegate implements Delegate<Object> {
453 
454         /**
455          * Creates the.
456          *
457          * @return the static delegate
458          */
459         static StaticDelegate create() {
460             return new StaticDelegate();
461         }
462 
463         /**
464          * Delegate method.
465          *
466          * @param i
467          *            the i
468          *
469          * @return true, if successful
470          */
471         boolean delegateMethod(int i) {
472             assertEquals(34, i);
473             return true;
474         }
475     }
476 
477     /**
478      * Delegate for native method.
479      *
480      * @param mock
481      *            the mock
482      */
483     @Test
484     void delegateForNativeMethod(@Mocked final Collaborator mock) {
485         new Expectations() {
486             {
487                 mock.nativeMethod(anyBoolean);
488                 result = new Delegate<Object>() {
489                     Long nativeMethod(boolean b) {
490                         assertTrue(b);
491                         return 0L;
492                     }
493                 };
494             }
495         };
496 
497         assertEquals(0L, new Collaborator().nativeMethod(true));
498     }
499 
500     /**
501      * Delegate for final method.
502      *
503      * @param mock
504      *            the mock
505      */
506     @Test
507     void delegateForFinalMethod(@Mocked final Collaborator mock) {
508         new Expectations() {
509             {
510                 mock.finalMethod();
511                 result = new Delegate<Object>() {
512                     char finalMethod() {
513                         return 'M';
514                     }
515                 };
516             }
517         };
518 
519         assertEquals('M', new Collaborator().finalMethod());
520     }
521 
522     /**
523      * Delegate for method with compatible but distinct parameter type.
524      *
525      * @param collaborator
526      *            the collaborator
527      */
528     @Test
529     void delegateForMethodWithCompatibleButDistinctParameterType(@Mocked final Collaborator collaborator) {
530         new Expectations() {
531             {
532                 collaborator.addElements(this.<List<String>> withNotNull());
533                 result = new Delegate<Object>() {
534                     void delegate(Collection<String> elements) {
535                         elements.add("test");
536                     }
537                 };
538             }
539         };
540 
541         List<String> elements = new ArrayList<>();
542         new Collaborator().addElements(elements);
543 
544         assertTrue(elements.contains("test"));
545     }
546 
547     /**
548      * Delegate receiving null arguments.
549      *
550      * @param collaborator
551      *            the collaborator
552      */
553     @Test
554     void delegateReceivingNullArguments(@Mocked final Collaborator collaborator) {
555         new Expectations() {
556             {
557                 collaborator.doSomething(true, null, null);
558                 result = new Delegate<Object>() {
559                     String delegate(boolean b, int[] i, String s) {
560                         // noinspection ImplicitArrayToString
561                         return b + " " + i + " " + s;
562                     }
563                 };
564             }
565         };
566 
567         String s = new Collaborator().doSomething(true, null, null);
568         assertEquals("true null null", s);
569     }
570 
571     /**
572      * Delegate with two methods.
573      *
574      * @param collaborator
575      *            the collaborator
576      */
577     @Test
578     void delegateWithTwoMethods(@Mocked final Collaborator collaborator) {
579         new Expectations() {
580             {
581                 collaborator.doSomething(true, null, "str");
582                 result = new Delegate<Object>() {
583                     private String someOther() {
584                         return "";
585                     }
586 
587                     void doSomething(boolean b, int[] i, String s) {
588                     }
589                 };
590             }
591         };
592 
593         assertNull(collaborator.doSomething(true, null, "str"));
594     }
595 
596     /**
597      * Delegate with single method having A different name.
598      *
599      * @param collaborator
600      *            the collaborator
601      */
602     @Test
603     void delegateWithSingleMethodHavingADifferentName(@Mocked final Collaborator collaborator) {
604         new Expectations() {
605             {
606                 collaborator.doSomething(true, null, "str");
607                 result = new Delegate<Object>() {
608                     void onReplay(boolean b, int[] i, String s) {
609                         assertTrue(b);
610                         assertNull(i);
611                         assertEquals("str", s);
612                     }
613                 };
614             }
615         };
616 
617         assertNull(new Collaborator().doSomething(true, null, "str"));
618     }
619 
620     /**
621      * Delegate with single method having no parameters.
622      *
623      * @param collaborator
624      *            the collaborator
625      */
626     @Test
627     void delegateWithSingleMethodHavingNoParameters(@Mocked final Collaborator collaborator) {
628         new Expectations() {
629             {
630                 collaborator.doSomething(anyBoolean, null, null);
631                 result = new Delegate<Object>() {
632                     String onReplay() {
633                         return "action";
634                     }
635                 };
636             }
637         };
638 
639         String result = new Collaborator().doSomething(true, null, null);
640 
641         assertEquals("action", result);
642     }
643 
644     /**
645      * Delegate with single method having no parameters except for invocation context.
646      *
647      * @param collaborator
648      *            the collaborator
649      */
650     @Test
651     void delegateWithSingleMethodHavingNoParametersExceptForInvocationContext(@Mocked final Collaborator collaborator) {
652         new Expectations() {
653             {
654                 collaborator.doSomething(anyBoolean, null, null);
655                 result = new Delegate<Object>() {
656                     void doSomething(Invocation inv) {
657                         assertEquals(1, inv.getInvocationCount());
658                     }
659                 };
660             }
661         };
662 
663         assertNull(new Collaborator().doSomething(false, new int[] { 1, 2 }, "test"));
664     }
665 
666     /**
667      * Delegate with one method having different parameters.
668      *
669      * @param collaborator
670      *            the collaborator
671      */
672     @Test
673     void delegateWithOneMethodHavingDifferentParameters(@Mocked final Collaborator collaborator) {
674         new Expectations() {
675             {
676                 collaborator.doSomething(true, null, "str");
677                 result = new Delegate<Object>() {
678                     void delegate(boolean b, String s) {
679                     }
680                 };
681             }
682         };
683 
684         Throwable throwable = assertThrows(IllegalArgumentException.class, () -> {
685             collaborator.doSomething(true, null, "str");
686         });
687         assertEquals("Failure to invoke method: void mockit.DelegateTest$18$1.delegate(boolean,java.lang.String)",
688                 throwable.getMessage());
689     }
690 
691     /**
692      * Delegate with two non private methods.
693      *
694      * @param collaborator
695      *            the collaborator
696      */
697     @Test
698     @ExpectedException(value = MissingInvocation.class)
699     void delegateWithTwoNonPrivateMethods(@Mocked final Collaborator collaborator) {
700         Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
701             new Expectations() {
702                 {
703                     collaborator.doSomething(true, null, "str");
704                     result = new Delegate<Object>() {
705                         String someOther() {
706                             return "";
707                         }
708 
709                         void doSomethingElse(boolean b, int[] i, String s) {
710                         }
711                     };
712                 }
713             };
714         });
715 
716         Assertions.assertTrue(exception.getMessage().contains("More than one candidate delegate method found: "));
717         Assertions.assertTrue(exception.getMessage().contains("someOther()"));
718         Assertions.assertTrue(exception.getMessage().contains("doSomethingElse(boolean,int[],String)"));
719     }
720 
721     /**
722      * Delegate causing concurrent mock invocation.
723      *
724      * @param mock
725      *            the mock
726      */
727     @Test
728     void delegateCausingConcurrentMockInvocation(@Mocked final Collaborator mock) {
729         final Collaborator collaborator = new Collaborator();
730         final Thread t = new Thread(new Runnable() {
731             @Override
732             public void run() {
733                 collaborator.doSomething(false, null, "");
734             }
735         });
736 
737         new Expectations() {
738             {
739                 mock.getValue();
740                 times = 1;
741                 result = new Delegate<Object>() {
742                     int executeInAnotherThread() throws Exception {
743                         t.start();
744                         t.join();
745                         return 1;
746                     }
747                 };
748             }
749         };
750 
751         assertEquals(1, collaborator.getValue());
752     }
753 
754     /**
755      * Delegate which calls the same mocked method.
756      *
757      * @param mock
758      *            the mock
759      */
760     @Test
761     void delegateWhichCallsTheSameMockedMethod(@Mocked final Collaborator mock) {
762         new Expectations() {
763             {
764                 mock.getValue();
765                 result = new Delegate<Object>() {
766                     int count;
767 
768                     // Would result in a StackOverflowError without a termination condition.
769                     int delegate() {
770                         return count++ > 1 ? 123 : 1 + mock.getValue();
771                     }
772                 };
773             }
774         };
775 
776         assertEquals(125, mock.getValue());
777     }
778 
779     /**
780      * Delegate which calls another mocked method.
781      *
782      * @param mock
783      *            the mock
784      */
785     @Test
786     void delegateWhichCallsAnotherMockedMethod(@Mocked final Collaborator mock) {
787         new Expectations() {
788             {
789                 mock.getValue();
790                 result = new Delegate<Object>() {
791                     int delegate() {
792                         return mock.finalMethod();
793                     }
794                 };
795 
796                 mock.finalMethod();
797                 result = 'A';
798             }
799         };
800 
801         assertEquals('A', mock.getValue());
802     }
803 
804     /**
805      * Delegate which calls another mocked method partial mocking of instance.
806      */
807     @Test
808     void delegateWhichCallsAnotherMockedMethod_partialMockingOfInstance() {
809         final Collaborator collaborator = new Collaborator();
810 
811         new Expectations(collaborator) {
812             {
813                 collaborator.getValue();
814                 result = new Delegate<Object>() {
815                     int delegate() {
816                         return collaborator.finalMethod();
817                     }
818                 };
819 
820                 collaborator.finalMethod();
821                 result = 'A';
822             }
823         };
824 
825         assertEquals('A', collaborator.getValue());
826     }
827 
828     /**
829      * Delegate which calls another mocked method injectable mocking.
830      *
831      * @param mock
832      *            the mock
833      */
834     @Test
835     void delegateWhichCallsAnotherMockedMethod_injectableMocking(@Injectable final Collaborator mock) {
836         new Expectations() {
837             {
838                 mock.getValue();
839                 result = new Delegate<Object>() {
840                     int delegate() {
841                         return mock.finalMethod();
842                     }
843                 };
844 
845                 mock.finalMethod();
846                 result = 'A';
847             }
848         };
849 
850         assertEquals('A', mock.getValue());
851     }
852 
853     /**
854      * Delegate which calls another mocked method producing A cascaded instance.
855      *
856      * @param mock
857      *            the mock
858      */
859     @Test
860     void delegateWhichCallsAnotherMockedMethodProducingACascadedInstance(@Mocked final Collaborator mock) {
861         new Expectations() {
862             {
863                 mock.getFoo().doSomething();
864                 result = 123;
865 
866                 mock.getValue();
867                 result = new Delegate<Object>() {
868                     int delegate() {
869                         return mock.getFoo().doSomething();
870                     }
871                 };
872             }
873         };
874 
875         assertEquals(123, mock.getFoo().doSomething());
876         assertEquals(123, mock.getValue());
877     }
878 
879     /**
880      * Delegate calling mocked method later verified.
881      *
882      * @param collaborator
883      *            the collaborator
884      * @param action
885      *            the action
886      */
887     @Test
888     void delegateCallingMockedMethodLaterVerified(@Mocked final Collaborator collaborator,
889             @Mocked final Runnable action) {
890         new Expectations() {
891             {
892                 collaborator.getFoo();
893                 result = new Delegate<Object>() {
894                     void delegate() {
895                         action.run();
896                     }
897                 };
898             }
899         };
900 
901         collaborator.getFoo();
902 
903         new Verifications() {
904             {
905                 action.run();
906             }
907         };
908     }
909 
910     /**
911      * Convert value returned from delegate when returns types differ.
912      *
913      * @param mock
914      *            the mock
915      */
916     @Test
917     void convertValueReturnedFromDelegateWhenReturnsTypesDiffer(@Mocked final Collaborator mock) {
918         new Expectations() {
919             {
920                 mock.getValue();
921                 result = new Delegate<Object>() {
922                     byte delegate() {
923                         return (byte) 123;
924                     }
925                 };
926             }
927         };
928 
929         int value = mock.getValue();
930 
931         assertEquals(123, value);
932     }
933 
934     /**
935      * Return inconvertible value from delegate when returns types differ.
936      *
937      * @param mock
938      *            the mock
939      */
940     @Test
941     void returnInconvertibleValueFromDelegateWhenReturnsTypesDiffer(@Mocked final Collaborator mock) {
942         new Expectations() {
943             {
944                 mock.getValue();
945                 result = new Delegate<Object>() {
946                     String delegate() {
947                         return "abc";
948                     }
949                 };
950             }
951         };
952 
953         Throwable throwable = assertThrows(IllegalArgumentException.class, () -> {
954             mock.getValue();
955         });
956         assertEquals(
957                 "Value of type String incompatible with return type int of mockit.DelegateTest$Collaborator#getValue()",
958                 throwable.getMessage());
959     }
960 
961     /**
962      * Return void from delegate method for recorded method having primitive return type.
963      *
964      * @param mock
965      *            the mock
966      */
967     @Test
968     void returnVoidFromDelegateMethodForRecordedMethodHavingPrimitiveReturnType(@Mocked final Collaborator mock) {
969         new Expectations() {
970             {
971                 mock.getValue();
972                 result = new Delegate<Object>() {
973                     void delegate() {
974                     }
975                 };
976             }
977         };
978 
979         Throwable throwable = assertThrows(IllegalArgumentException.class, () -> {
980             mock.getValue();
981         });
982         assertEquals(
983                 "void return type incompatible with return type int of mockit.DelegateTest$Collaborator#getValue()",
984                 throwable.getMessage());
985     }
986 
987     /**
988      * Return byte array from delegate method.
989      *
990      * @param mock
991      *            the mock
992      */
993     @Test
994     void returnByteArrayFromDelegateMethod(@Mocked final Collaborator mock) {
995         final byte[] bytes = "test".getBytes();
996         new Expectations() {
997             {
998                 mock.getArray();
999                 result = new Delegate<Object>() {
1000                     byte[] delegate() {
1001                         return bytes;
1002                     }
1003                 };
1004             }
1005         };
1006 
1007         assertSame(bytes, mock.getArray());
1008     }
1009 
1010     /**
1011      * Return value of correct type from delegate method returning A supertype.
1012      *
1013      * @param mock
1014      *            the mock
1015      */
1016     @Test
1017     void returnValueOfCorrectTypeFromDelegateMethodReturningASupertype(@Mocked final Collaborator mock) {
1018         final Foo expected = new Foo();
1019 
1020         new Expectations() {
1021             {
1022                 mock.getFoo();
1023                 result = new Delegate<Object>() {
1024                     Object delegate() {
1025                         return expected;
1026                     }
1027                 };
1028             }
1029         };
1030 
1031         Foo actual = mock.getFoo();
1032 
1033         assertSame(expected, actual);
1034     }
1035 }