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 java.util.Arrays.asList;
9   
10  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
11  import static org.junit.jupiter.api.Assertions.assertEquals;
12  import static org.junit.jupiter.api.Assertions.assertFalse;
13  import static org.junit.jupiter.api.Assertions.assertNull;
14  import static org.junit.jupiter.api.Assertions.assertSame;
15  import static org.junit.jupiter.api.Assertions.assertTrue;
16  import static org.junit.jupiter.api.Assertions.fail;
17  
18  import java.math.BigDecimal;
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.LinkedHashSet;
26  import java.util.List;
27  import java.util.ListIterator;
28  import java.util.Map;
29  import java.util.NoSuchElementException;
30  import java.util.Queue;
31  import java.util.Set;
32  import java.util.SortedMap;
33  import java.util.SortedSet;
34  import java.util.TreeSet;
35  import java.util.concurrent.Callable;
36  
37  import mockit.integration.junit5.ExpectedException;
38  import mockit.integration.junit5.JMockitExtension;
39  import mockit.internal.expectations.invocation.MissingInvocation;
40  
41  import org.junit.jupiter.api.Assertions;
42  import org.junit.jupiter.api.Test;
43  import org.junit.jupiter.api.extension.ExtendWith;
44  
45  /**
46   * The Class ExpectationsUsingResultFieldTest.
47   */
48  @ExtendWith(JMockitExtension.class)
49  class ExpectationsUsingResultFieldTest {
50  
51      /**
52       * The Class Collaborator.
53       */
54      static class Collaborator {
55  
56          /**
57           * Do internal.
58           *
59           * @return the string
60           */
61          static String doInternal() {
62              return "123";
63          }
64  
65          /**
66           * Provide some service.
67           */
68          void provideSomeService() {
69          }
70  
71          /**
72           * Gets the value.
73           *
74           * @return the value
75           */
76          int getValue() {
77              return -1;
78          }
79  
80          /**
81           * Gets the integer.
82           *
83           * @return the integer
84           */
85          Integer getInteger() {
86              return -1;
87          }
88  
89          /**
90           * Gets the byte value.
91           *
92           * @return the byte value
93           */
94          byte getByteValue() {
95              return -1;
96          }
97  
98          /**
99           * Gets the byte wrapper.
100          *
101          * @return the byte wrapper
102          */
103         Byte getByteWrapper() {
104             return -1;
105         }
106 
107         /**
108          * Gets the short value.
109          *
110          * @return the short value
111          */
112         short getShortValue() {
113             return -1;
114         }
115 
116         /**
117          * Gets the short wrapper.
118          *
119          * @return the short wrapper
120          */
121         Short getShortWrapper() {
122             return -1;
123         }
124 
125         /**
126          * Gets the long value.
127          *
128          * @return the long value
129          */
130         long getLongValue() {
131             return -1;
132         }
133 
134         /**
135          * Gets the long wrapper.
136          *
137          * @return the long wrapper
138          */
139         Long getLongWrapper() {
140             return -1L;
141         }
142 
143         /**
144          * Gets the float value.
145          *
146          * @return the float value
147          */
148         float getFloatValue() {
149             return -1.0F;
150         }
151 
152         /**
153          * Gets the float wrapper.
154          *
155          * @return the float wrapper
156          */
157         Float getFloatWrapper() {
158             return -1.0F;
159         }
160 
161         /**
162          * Gets the double value.
163          *
164          * @return the double value
165          */
166         double getDoubleValue() {
167             return -1.0;
168         }
169 
170         /**
171          * Gets the double wrapper.
172          *
173          * @return the double wrapper
174          */
175         Double getDoubleWrapper() {
176             return -1.0;
177         }
178 
179         /**
180          * Gets the char value.
181          *
182          * @return the char value
183          */
184         char getCharValue() {
185             return '1';
186         }
187 
188         /**
189          * Gets the character.
190          *
191          * @return the character
192          */
193         Character getCharacter() {
194             return '1';
195         }
196 
197         /**
198          * Gets the boolean value.
199          *
200          * @return the boolean value
201          */
202         boolean getBooleanValue() {
203             return true;
204         }
205 
206         /**
207          * Gets the boolean wrapper.
208          *
209          * @return the boolean wrapper
210          */
211         Boolean getBooleanWrapper() {
212             return true;
213         }
214 
215         /**
216          * Gets the string.
217          *
218          * @return the string
219          */
220         String getString() {
221             return "";
222         }
223 
224         /**
225          * Gets the object.
226          *
227          * @return the object
228          */
229         Object getObject() {
230             return null;
231         }
232 
233         /**
234          * Gets the items.
235          *
236          * @return the items
237          */
238         Collection<?> getItems() {
239             return null;
240         }
241 
242         /**
243          * Gets the list items.
244          *
245          * @return the list items
246          */
247         List<?> getListItems() {
248             return null;
249         }
250 
251         /**
252          * Gets the sets the items.
253          *
254          * @return the sets the items
255          */
256         Set<?> getSetItems() {
257             return null;
258         }
259 
260         /**
261          * Gets the sorted set items.
262          *
263          * @return the sorted set items
264          */
265         SortedSet<?> getSortedSetItems() {
266             return null;
267         }
268 
269         /**
270          * Gets the map items.
271          *
272          * @return the map items
273          */
274         Map<?, ?> getMapItems() {
275             return null;
276         }
277 
278         /**
279          * Gets the sorted map items.
280          *
281          * @return the sorted map items
282          */
283         SortedMap<?, ?> getSortedMapItems() {
284             return null;
285         }
286 
287         /**
288          * Gets the iterator.
289          *
290          * @return the iterator
291          */
292         Iterator<?> getIterator() {
293             return null;
294         }
295 
296         /**
297          * Gets the list iterator.
298          *
299          * @return the list iterator
300          */
301         ListIterator<?> getListIterator() {
302             return null;
303         }
304 
305         /**
306          * Gets the iterable.
307          *
308          * @return the iterable
309          */
310         Iterable<?> getIterable() {
311             return null;
312         }
313 
314         /**
315          * Gets the int array.
316          *
317          * @return the int array
318          */
319         int[] getIntArray() {
320             return null;
321         }
322 
323         /**
324          * Gets the int 2 array.
325          *
326          * @return the int 2 array
327          */
328         int[][] getInt2Array() {
329             return null;
330         }
331 
332         /**
333          * Gets the byte array.
334          *
335          * @return the byte array
336          */
337         byte[] getByteArray() {
338             return null;
339         }
340 
341         /**
342          * Gets the short array.
343          *
344          * @return the short array
345          */
346         short[] getShortArray() {
347             return null;
348         }
349 
350         /**
351          * Gets the short wrapper array.
352          *
353          * @return the short wrapper array
354          */
355         Short[] getShortWrapperArray() {
356             return null;
357         }
358 
359         /**
360          * Gets the long array.
361          *
362          * @return the long array
363          */
364         long[] getLongArray() {
365             return null;
366         }
367 
368         /**
369          * Gets the long 2 array.
370          *
371          * @return the long 2 array
372          */
373         long[][] getLong2Array() {
374             return null;
375         }
376 
377         /**
378          * Gets the float array.
379          *
380          * @return the float array
381          */
382         float[] getFloatArray() {
383             return null;
384         }
385 
386         /**
387          * Gets the double array.
388          *
389          * @return the double array
390          */
391         double[] getDoubleArray() {
392             return null;
393         }
394 
395         /**
396          * Gets the char array.
397          *
398          * @return the char array
399          */
400         char[] getCharArray() {
401             return null;
402         }
403 
404         /**
405          * Gets the boolean array.
406          *
407          * @return the boolean array
408          */
409         boolean[] getBooleanArray() {
410             return null;
411         }
412 
413         /**
414          * Gets the string array.
415          *
416          * @return the string array
417          */
418         String[] getStringArray() {
419             return null;
420         }
421 
422         /**
423          * Gets the string 2 array.
424          *
425          * @return the string 2 array
426          */
427         String[][] getString2Array() {
428             return null;
429         }
430 
431         /**
432          * Gets the array of generic elements.
433          *
434          * @param <T>
435          *            the generic type
436          * @param i
437          *            the i
438          *
439          * @return the array of generic elements
440          */
441         <T extends Number> T[] getArrayOfGenericElements(@SuppressWarnings("unused") int i) {
442             return null;
443         }
444 
445         /**
446          * Gets the numbers.
447          *
448          * @return the numbers
449          */
450         Collection<Number> getNumbers() {
451             return null;
452         }
453 
454         /**
455          * Gets the number list.
456          *
457          * @return the number list
458          */
459         List<Number> getNumberList() {
460             return null;
461         }
462 
463         /**
464          * Gets the string set.
465          *
466          * @return the string set
467          */
468         Set<String> getStringSet() {
469             return null;
470         }
471 
472         /**
473          * Gets the sorted number set.
474          *
475          * @return the sorted number set
476          */
477         SortedSet<Number> getSortedNumberSet() {
478             return null;
479         }
480 
481         /**
482          * Gets the string iterator.
483          *
484          * @return the string iterator
485          */
486         Iterator<String> getStringIterator() {
487             return null;
488         }
489 
490         /**
491          * Gets the float iterator.
492          *
493          * @return the float iterator
494          */
495         ListIterator<Float> getFloatIterator() {
496             return null;
497         }
498 
499         /**
500          * Gets the number iterable.
501          *
502          * @return the number iterable
503          */
504         Iterable<Number> getNumberIterable() {
505             return null;
506         }
507 
508         /**
509          * Gets the number queue.
510          *
511          * @return the number queue
512          */
513         Queue<Number> getNumberQueue() {
514             return null;
515         }
516     }
517 
518     /**
519      * Returns expected values.
520      *
521      * @param mock
522      *            the mock
523      */
524     @Test
525     void returnsExpectedValues(@Mocked final Collaborator mock) {
526         new Expectations() {
527             {
528                 mock.getValue();
529                 result = 3;
530                 Collaborator.doInternal();
531                 result = "test";
532             }
533         };
534 
535         assertEquals(3, mock.getValue());
536         assertEquals("test", Collaborator.doInternal());
537     }
538 
539     /**
540      * Record thrown exception.
541      *
542      * @param mock
543      *            the mock
544      */
545     @Test
546     @ExpectedException(ArithmeticException.class)
547     void recordThrownException(@Mocked final Collaborator mock) {
548 
549         new Expectations() {
550             {
551                 mock.provideSomeService();
552                 result = new ArithmeticException("test");
553             }
554         };
555 
556         mock.provideSomeService();
557     }
558 
559     /**
560      * Record thrown error.
561      *
562      * @param mock
563      *            the mock
564      */
565     @Test
566     @ExpectedException(LinkageError.class)
567     void recordThrownError(@Mocked final Collaborator mock) {
568         new Expectations() {
569             {
570                 mock.provideSomeService();
571                 result = new LinkageError("test");
572             }
573         };
574 
575         mock.provideSomeService();
576     }
577 
578     /**
579      * Returns multiple expected values.
580      *
581      * @param mock
582      *            the mock
583      */
584     @Test
585     void returnsMultipleExpectedValues(@Mocked final Collaborator mock) {
586         new Expectations() {
587             {
588                 mock.getValue();
589                 result = 1;
590                 result = 2;
591                 result = 3;
592             }
593         };
594 
595         assertEquals(1, mock.getValue());
596         assertEquals(2, mock.getValue());
597         assertEquals(3, mock.getValue());
598     }
599 
600     /**
601      * Returns multiple expected values with more invocations allowed.
602      *
603      * @param mock
604      *            the mock
605      */
606     @Test
607     void returnsMultipleExpectedValuesWithMoreInvocationsAllowed(@Mocked final Collaborator mock) {
608         new Expectations() {
609             {
610                 mock.getValue();
611                 result = 1;
612                 result = 2;
613                 times = 3;
614             }
615         };
616 
617         assertEquals(1, mock.getValue());
618         assertEquals(2, mock.getValue());
619         assertEquals(2, mock.getValue());
620     }
621 
622     /**
623      * Returns null as default value for methods returning string or object.
624      *
625      * @param mock
626      *            the mock
627      */
628     @Test
629     void returnsNullAsDefaultValueForMethodsReturningStringOrObject(@Mocked Collaborator mock) {
630         assertNull(mock.getString());
631         assertNull(Collaborator.doInternal());
632         assertNull(mock.getObject());
633     }
634 
635     /**
636      * Returns default values for primitive and wrapper return types.
637      *
638      * @param mock
639      *            the mock
640      */
641     @Test
642     void returnsDefaultValuesForPrimitiveAndWrapperReturnTypes(@Mocked Collaborator mock) {
643         assertEquals(0, mock.getValue());
644         assertEquals(0, mock.getInteger().intValue());
645         assertEquals((byte) 0, mock.getByteValue());
646         assertEquals(0, mock.getByteWrapper().intValue());
647         assertEquals((short) 0, mock.getShortValue());
648         assertEquals(0, mock.getShortWrapper().intValue());
649         assertEquals(0L, mock.getLongValue());
650         assertEquals(0L, mock.getLongWrapper().longValue());
651         assertEquals(0.0F, mock.getFloatValue(), 0.0);
652         assertEquals(0.0F, mock.getFloatWrapper(), 0);
653         assertEquals(0.0, mock.getDoubleValue(), 0.0);
654         assertEquals(0.0, mock.getDoubleWrapper(), 0);
655         assertEquals('\0', mock.getCharValue());
656         assertEquals('\0', mock.getCharacter().charValue());
657         assertFalse(mock.getBooleanValue());
658         assertFalse(mock.getBooleanWrapper());
659     }
660 
661     /**
662      * Returns default values for collection valued return types.
663      *
664      * @param mock
665      *            the mock
666      */
667     @Test
668     void returnsDefaultValuesForCollectionValuedReturnTypes(@Mocked Collaborator mock) {
669         List<?> emptyList = Collections.emptyList();
670         assertSame(emptyList, mock.getItems());
671         assertSame(emptyList, mock.getListItems());
672 
673         Set<?> emptySet = Collections.emptySet();
674         assertSame(emptySet, mock.getSetItems());
675         assertEquals(emptySet, mock.getSortedSetItems());
676 
677         Map<?, ?> emptyMap = Collections.emptyMap();
678         assertSame(emptyMap, mock.getMapItems());
679         assertEquals(emptyMap, mock.getSortedMapItems());
680     }
681 
682     /**
683      * Returns default values for iterator and iterable return types.
684      *
685      * @param mock
686      *            the mock
687      */
688     @Test
689     void returnsDefaultValuesForIteratorAndIterableReturnTypes(@Mocked Collaborator mock) {
690         assertFalse(mock.getIterator().hasNext());
691         assertFalse(mock.getListIterator().hasNext());
692         assertFalse(mock.getIterable().iterator().hasNext());
693     }
694 
695     /**
696      * Returns default values for array valued return types.
697      *
698      * @param mock
699      *            the mock
700      */
701     @Test
702     void returnsDefaultValuesForArrayValuedReturnTypes(@Mocked Collaborator mock) {
703         assertArrayEquals(new int[0], mock.getIntArray());
704         assertArrayEquals(new int[0][0], mock.getInt2Array());
705         assertArrayEquals(new byte[0], mock.getByteArray());
706         assertArrayEquals(new short[0], mock.getShortArray());
707         assertArrayEquals(new Short[0], mock.getShortWrapperArray());
708         assertArrayEquals(new long[0], mock.getLongArray());
709         assertArrayEquals(new long[0][0], mock.getLong2Array());
710         assertArrayEquals(new float[0], mock.getFloatArray(), 0.0F);
711         assertArrayEquals(new double[0], mock.getDoubleArray(), 0.0);
712         assertArrayEquals(new char[0], mock.getCharArray());
713         assertEquals(0, mock.getBooleanArray().length);
714         assertArrayEquals(new String[0], mock.getStringArray());
715         assertArrayEquals(new String[0][0], mock.getString2Array());
716     }
717 
718     /**
719      * Returns multiple values in sequence using collection.
720      */
721     @Test
722     void returnsMultipleValuesInSequenceUsingCollection() {
723         final Collaborator collaborator = new Collaborator();
724         final Set<Boolean> booleanSet = new LinkedHashSet<>(asList(true, false));
725         final Collection<Integer> intCol = asList(1, 2, 3);
726         final List<Character> charList = asList('a', 'b', 'c');
727 
728         new Expectations(collaborator) {
729             {
730                 collaborator.getBooleanWrapper();
731                 result = booleanSet;
732                 collaborator.getInteger();
733                 result = intCol;
734                 collaborator.getCharValue();
735                 result = charList;
736             }
737         };
738 
739         assertTrue(collaborator.getBooleanWrapper());
740         assertFalse(collaborator.getBooleanWrapper());
741 
742         assertEquals(1, collaborator.getInteger().intValue());
743         assertEquals(2, collaborator.getInteger().intValue());
744         assertEquals(3, collaborator.getInteger().intValue());
745 
746         assertEquals('a', collaborator.getCharValue());
747         assertEquals('b', collaborator.getCharValue());
748         assertEquals('c', collaborator.getCharValue());
749     }
750 
751     /**
752      * Returns multiple values in sequence using iterator.
753      */
754     @Test
755     void returnsMultipleValuesInSequenceUsingIterator() {
756         final Collaborator collaborator = new Collaborator();
757         final Collection<String> strCol = asList("ab", "cde", "Xyz");
758 
759         new Expectations(collaborator) {
760             {
761                 collaborator.getString();
762                 result = strCol.iterator();
763             }
764         };
765 
766         assertEquals("ab", collaborator.getString());
767         assertEquals("cde", collaborator.getString());
768         assertEquals("Xyz", collaborator.getString());
769     }
770 
771     /**
772      * Returns multiple values in sequence using array.
773      *
774      * @param collaborator
775      *            the collaborator
776      */
777     @Test
778     void returnsMultipleValuesInSequenceUsingArray(@Injectable final Collaborator collaborator) {
779         final boolean[] arrayOfBooleanPrimitives = { true, false };
780         final Boolean[] arrayOfBooleanWrappers = { Boolean.TRUE, Boolean.FALSE };
781         final int[] intArray = { 1, 2, 3 };
782         final Character[] charArray = { 'a', 'b', 'c' };
783 
784         new Expectations() {
785             {
786                 collaborator.getBooleanValue();
787                 result = arrayOfBooleanPrimitives;
788                 collaborator.getBooleanWrapper();
789                 result = arrayOfBooleanWrappers;
790                 collaborator.getValue();
791                 result = intArray;
792                 collaborator.getCharValue();
793                 result = charArray;
794             }
795         };
796 
797         assertTrue(collaborator.getBooleanValue());
798         assertFalse(collaborator.getBooleanValue());
799 
800         assertTrue(collaborator.getBooleanWrapper());
801         assertFalse(collaborator.getBooleanWrapper());
802 
803         assertEquals(1, collaborator.getValue());
804         assertEquals(2, collaborator.getValue());
805         assertEquals(3, collaborator.getValue());
806 
807         assertEquals('a', collaborator.getCharValue());
808         assertEquals('b', collaborator.getCharValue());
809         assertEquals('c', collaborator.getCharValue());
810     }
811 
812     /**
813      * Returns multiple values in sequence using iterable.
814      *
815      * @param collaborator
816      *            the collaborator
817      */
818     @Test
819     void returnsMultipleValuesInSequenceUsingIterable(@Injectable final Collaborator collaborator) {
820         final Iterable<Integer> intValues = () -> asList(3, 2, 1).iterator();
821 
822         new Expectations() {
823             {
824                 collaborator.getValue();
825                 result = intValues;
826             }
827         };
828 
829         assertEquals(3, collaborator.getValue());
830         assertEquals(2, collaborator.getValue());
831         assertEquals(1, collaborator.getValue());
832     }
833 
834     /**
835      * Returns multiple values from method with return type of object.
836      *
837      * @param collaborator
838      *            the collaborator
839      */
840     @Test
841     void returnsMultipleValuesFromMethodWithReturnTypeOfObject(@Mocked final Collaborator collaborator) {
842         new Expectations() {
843             {
844                 collaborator.getObject();
845                 result = new int[] { 1, 2 };
846                 result = new Object[] { "test", 'X' };
847                 result = asList(5L, 67L);
848                 result = null;
849             }
850         };
851 
852         assertArrayEquals(new int[] { 1, 2 }, (int[]) collaborator.getObject());
853         assertArrayEquals(new Object[] { "test", 'X' }, (Object[]) collaborator.getObject());
854         assertEquals(asList(5L, 67L), collaborator.getObject());
855         assertNull(collaborator.getObject());
856         assertNull(collaborator.getObject());
857     }
858 
859     /**
860      * Returns empty array for method with return type of object.
861      *
862      * @param mock
863      *            the mock
864      */
865     @Test
866     void returnsEmptyArrayForMethodWithReturnTypeOfObject(@Mocked final Collaborator mock) {
867         final String[] emptyArray = {};
868 
869         new Expectations() {
870             {
871                 mock.getObject();
872                 result = emptyArray;
873             }
874         };
875 
876         assertSame(emptyArray, mock.getObject());
877     }
878 
879     /**
880      * Returns multiple values from generic method.
881      *
882      * @param callable
883      *            the callable
884      *
885      * @throws Exception
886      *             the exception
887      */
888     @Test
889     void returnsMultipleValuesFromGenericMethod(@Mocked final Callable<Integer> callable) throws Exception {
890         new Expectations() {
891             {
892                 callable.call();
893                 result = new int[] { 3, 2, 1 };
894             }
895         };
896 
897         Integer firstCall = callable.call();
898         assertEquals(3, firstCall.intValue());
899         assertEquals(2, callable.call().intValue());
900         assertEquals(1, callable.call().intValue());
901     }
902 
903     /**
904      * Returns specified collections for methods that return collections.
905      */
906     @Test
907     void returnsSpecifiedCollectionsForMethodsThatReturnCollections() {
908         final Collaborator collaborator = new Collaborator();
909         final Collection<String> strCol = asList("ab", "cde");
910         final List<Byte> byteList = asList((byte) 5, (byte) 68);
911         final Set<Character> charSet = new HashSet<>(asList('g', 't', 'x'));
912         final SortedSet<String> sortedSet = new TreeSet<>(asList("hpq", "Abc"));
913 
914         new Expectations(collaborator) {
915             {
916                 collaborator.getItems();
917                 result = strCol;
918                 collaborator.getListItems();
919                 result = byteList;
920                 collaborator.getSetItems();
921                 result = charSet;
922                 collaborator.getSortedSetItems();
923                 result = sortedSet;
924             }
925         };
926 
927         assertSame(strCol, collaborator.getItems());
928         assertSame(byteList, collaborator.getListItems());
929         assertSame(charSet, collaborator.getSetItems());
930         assertSame(sortedSet, collaborator.getSortedSetItems());
931     }
932 
933     /**
934      * Returns specified iterator for method that returns iterator.
935      */
936     @Test
937     void returnsSpecifiedIteratorForMethodThatReturnsIterator() {
938         final Collaborator collaborator = new Collaborator();
939         final Iterator<String> itr = asList("ab", "cde").iterator();
940 
941         new Expectations(collaborator) {
942             {
943                 collaborator.getIterator();
944                 result = itr;
945             }
946         };
947 
948         assertSame(itr, collaborator.getIterator());
949     }
950 
951     /**
952      * Returns value of incompatible type for method returning array.
953      *
954      * @param mock
955      *            the mock
956      */
957     @Test
958     void returnsValueOfIncompatibleTypeForMethodReturningArray(@Mocked final Collaborator mock) {
959         new Expectations() {
960             {
961                 mock.getBooleanArray();
962                 result = new HashSet<Object>();
963                 mock.getStringArray();
964                 result = Collections.emptyList();
965                 mock.getIntArray();
966                 result = new short[] { 1, 2 };
967             }
968         };
969 
970         try {
971             mock.getBooleanArray();
972             fail();
973         } catch (ClassCastException ignore) {
974         }
975         try {
976             mock.getStringArray();
977             fail();
978         } catch (ClassCastException ignore) {
979         }
980         try {
981             mock.getIntArray();
982             fail();
983         } catch (ClassCastException ignore) {
984         }
985     }
986 
987     /**
988      * Returns value of incompatible type for method returning collection.
989      *
990      * @param mock
991      *            the mock
992      */
993     @Test
994     void returnsValueOfIncompatibleTypeForMethodReturningCollection(@Mocked final Collaborator mock) {
995         new Expectations() {
996             {
997                 mock.getListItems();
998                 result = Collections.emptySet();
999                 mock.getSetItems();
1000                 result = new ArrayList<Object>();
1001             }
1002         };
1003 
1004         try {
1005             mock.getListItems();
1006             fail();
1007         } catch (ClassCastException ignore) {
1008         }
1009         try {
1010             mock.getSetItems();
1011             fail();
1012         } catch (ClassCastException ignore) {
1013         }
1014     }
1015 
1016     /**
1017      * Attempt to return value of type set from method returning iterator.
1018      *
1019      * @param mock
1020      *            the mock
1021      */
1022     @Test
1023     void attemptToReturnValueOfTypeSetFromMethodReturningIterator(@Mocked final Collaborator mock) {
1024         new Expectations() {
1025             {
1026                 mock.getIterator();
1027                 result = Collections.emptySet();
1028             }
1029         };
1030 
1031         Assertions.assertThrows(ClassCastException.class, () -> mock.getIterator());
1032     }
1033 
1034     /**
1035      * Attempt to return value of type list from method returning iterator.
1036      *
1037      * @param mock
1038      *            the mock
1039      */
1040     @Test
1041     void attemptToReturnValueOfTypeListFromMethodReturningIterator(@Mocked final Collaborator mock) {
1042         new Expectations() {
1043             {
1044                 mock.getIterator();
1045                 result = asList("a", true, 123);
1046             }
1047         };
1048 
1049         Assertions.assertThrows(ClassCastException.class, () -> mock.getIterator());
1050     }
1051 
1052     /**
1053      * Return iterable or iterator from recorded array.
1054      *
1055      * @param mock
1056      *            the mock
1057      */
1058     @Test
1059     void returnIterableOrIteratorFromRecordedArray(@Injectable final Collaborator mock) {
1060         final String[] items = { "Abc", "test" };
1061         final int[] listItems = { 1, 2, 3 };
1062         final boolean[] iterable = { false, true };
1063         final Boolean[] iterator = { true, false, true };
1064         final Object[] listIterator = { "test", 123, true };
1065 
1066         new Expectations() {
1067             {
1068                 mock.getItems();
1069                 result = items;
1070                 mock.getListItems();
1071                 result = listItems;
1072                 mock.getSetItems();
1073                 result = new char[] { 'A', 'c', 'b', 'A' };
1074                 mock.getSortedSetItems();
1075                 result = new Object[] { "test", "123", "abc" };
1076                 mock.getIterable();
1077                 result = iterable;
1078                 mock.getIterator();
1079                 result = iterator;
1080                 mock.getListIterator();
1081                 result = listIterator;
1082             }
1083         };
1084 
1085         assertEquals(Arrays.toString(items), mock.getItems().toString());
1086         assertEquals(Arrays.toString(listItems), mock.getListItems().toString());
1087         assertEquals("[A, c, b]", mock.getSetItems().toString());
1088         assertEquals("[123, abc, test]", mock.getSortedSetItems().toString());
1089         assertEquals(Arrays.toString(iterable), mock.getIterable().toString());
1090         assertEquals(asList(iterator), fromIterator(mock.getIterator()));
1091         assertEquals(asList(listIterator), fromIterator(mock.getListIterator()));
1092     }
1093 
1094     /**
1095      * From iterator.
1096      *
1097      * @param itr
1098      *            the itr
1099      *
1100      * @return the list
1101      */
1102     private List<?> fromIterator(Iterator<?> itr) {
1103         List<Object> values = new ArrayList<>();
1104 
1105         while (itr.hasNext()) {
1106             values.add(itr.next());
1107         }
1108 
1109         return values;
1110     }
1111 
1112     /**
1113      * Return map from recorded two dimensional array.
1114      *
1115      * @param mock1
1116      *            the mock 1
1117      * @param mock2
1118      *            the mock 2
1119      */
1120     @Test
1121     void returnMapFromRecordedTwoDimensionalArray(@Injectable final Collaborator mock1,
1122             @Injectable final Collaborator mock2) {
1123         final int[][] sortedItems1 = { { 13, 1 }, { 2, 2 }, { 31, 3 }, { 5, 4 } };
1124         final Object[][] items2 = { { 1, "first" }, { 2 }, { 3, true } };
1125 
1126         new Expectations() {
1127             {
1128                 mock1.getMapItems();
1129                 result = new String[][] { { "Abc", "first" }, { "test", "Second" }, { "Xyz", null } };
1130                 mock1.getSortedMapItems();
1131                 result = sortedItems1;
1132                 mock2.getMapItems();
1133                 result = items2;
1134             }
1135         };
1136 
1137         assertEquals("{Abc=first, test=Second, Xyz=null}", mock1.getMapItems().toString());
1138         assertEquals("{2=2, 5=4, 13=1, 31=3}", mock1.getSortedMapItems().toString());
1139         assertEquals("{1=first, 2=null, 3=true}", mock2.getMapItems().toString());
1140     }
1141 
1142     /**
1143      * Record null return value for constructor.
1144      *
1145      * @param mock
1146      *            the mock
1147      */
1148     @Test
1149     void recordNullReturnValueForConstructor(@Mocked Collaborator mock) {
1150         new Expectations() {
1151             {
1152                 new Collaborator();
1153                 result = null;
1154             }
1155         };
1156 
1157         new Collaborator().provideSomeService();
1158     }
1159 
1160     /**
1161      * Record null return value for void method.
1162      *
1163      * @param mock
1164      *            the mock
1165      */
1166     @Test
1167     void recordNullReturnValueForVoidMethod(@Mocked final Collaborator mock) {
1168         new Expectations() {
1169             {
1170                 mock.provideSomeService();
1171                 result = null;
1172             }
1173         };
1174 
1175         new Collaborator().provideSomeService();
1176     }
1177 
1178     /**
1179      * Record null return value for void method and then A thrown error.
1180      *
1181      * @param mock
1182      *            the mock
1183      */
1184     @Test
1185     @ExpectedException(UnknownError.class)
1186     void recordNullReturnValueForVoidMethodAndThenAThrownError(@Mocked final Collaborator mock) {
1187         new Expectations() {
1188             {
1189                 mock.provideSomeService();
1190                 result = null;
1191                 result = new UnknownError();
1192             }
1193         };
1194 
1195         try {
1196             mock.provideSomeService();
1197         } catch (Throwable ignore) {
1198             fail();
1199         }
1200 
1201         mock.provideSomeService();
1202     }
1203 
1204     /**
1205      * Throw exception from second invocation of constructor.
1206      *
1207      * @param mock
1208      *            the mock
1209      */
1210     @Test
1211     @ExpectedException(NoSuchElementException.class)
1212     void throwExceptionFromSecondInvocationOfConstructor(@Mocked Collaborator mock) {
1213         new Expectations() {
1214             {
1215                 new Collaborator();
1216                 result = null;
1217                 result = new NoSuchElementException();
1218             }
1219         };
1220 
1221         try {
1222             new Collaborator();
1223         } catch (NoSuchElementException ignore) {
1224             fail();
1225         }
1226 
1227         new Collaborator();
1228     }
1229 
1230     /**
1231      * Record return value for void method.
1232      *
1233      * @param mock
1234      *            the mock
1235      */
1236     @Test
1237     @ExpectedException(value = MissingInvocation.class)
1238     void recordReturnValueForVoidMethod(@Mocked final Collaborator mock) {
1239         Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
1240             new Expectations() {
1241                 {
1242                     mock.provideSomeService();
1243                     result = 123;
1244                 }
1245             };
1246         });
1247         assertTrue(exception.getMessage().contains("Value of type Integer incompatible with return type void"));
1248     }
1249 
1250     /**
1251      * Record consecutive return values for void method.
1252      *
1253      * @param mock
1254      *            the mock
1255      */
1256     @Test
1257     void recordConsecutiveReturnValuesForVoidMethod(@Mocked final Collaborator mock) {
1258         new Expectations() {
1259             {
1260                 mock.provideSomeService();
1261                 result = new int[] { 123, 45 }; // will have the effect of allowing two invocations
1262             }
1263         };
1264 
1265         mock.provideSomeService();
1266         mock.provideSomeService();
1267     }
1268 
1269     /**
1270      * Record return value for constructor.
1271      *
1272      * @param mock
1273      *            the mock
1274      */
1275     @Test
1276     @ExpectedException(MissingInvocation.class)
1277     void recordReturnValueForConstructor(@Mocked Collaborator mock) {
1278         Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
1279             new Expectations() {
1280                 {
1281                     new Collaborator();
1282                     result = "test"; // invalid, throws IllegalArgumentException
1283                 }
1284             };
1285         });
1286         assertTrue(exception.getMessage().contains("Invalid assignment to result field for constructor expectation"));
1287     }
1288 
1289     /**
1290      * Record return values mixed with throwables for non void method.
1291      *
1292      * @param mock
1293      *            the mock
1294      */
1295     @Test
1296     void recordReturnValuesMixedWithThrowablesForNonVoidMethod(@Mocked final Collaborator mock) {
1297         new Expectations() {
1298             {
1299                 mock.getString();
1300                 result = asList("Abc", new IllegalStateException(), "DEF", null, new UnknownError());
1301             }
1302         };
1303 
1304         Collaborator c = new Collaborator();
1305         assertEquals("Abc", c.getString());
1306         try {
1307             c.getString();
1308             fail();
1309         } catch (IllegalStateException ignored) {
1310         }
1311         assertEquals("DEF", c.getString());
1312         assertNull(c.getString());
1313         try {
1314             c.getString();
1315             fail();
1316         } catch (UnknownError ignored) {
1317         }
1318         try {
1319             c.getString();
1320             fail();
1321         } catch (UnknownError ignored) {
1322         }
1323     }
1324 
1325     /**
1326      * Record exception followed by null return value for void method.
1327      *
1328      * @param mock
1329      *            the mock
1330      */
1331     @Test
1332     void recordExceptionFollowedByNullReturnValueForVoidMethod(@Mocked final Collaborator mock) {
1333         new Expectations() {
1334             {
1335                 mock.provideSomeService();
1336                 result = new IllegalArgumentException();
1337                 result = null;
1338             }
1339         };
1340 
1341         try {
1342             mock.provideSomeService();
1343             fail();
1344         } catch (IllegalArgumentException ignored) {
1345         }
1346         mock.provideSomeService();
1347     }
1348 
1349     /**
1350      * Record arrays of generic element types.
1351      *
1352      * @param mock
1353      *            the mock
1354      */
1355     @Test
1356     void recordArraysOfGenericElementTypes(@Mocked final Collaborator mock) {
1357         final Integer[] integerValues = { 1, 2 };
1358         final Number[] numberValues = { 5L, 12.5F };
1359         final String[] stringValues = { "a", "b" };
1360 
1361         new Expectations() {
1362             {
1363                 mock.getArrayOfGenericElements(1);
1364                 result = integerValues;
1365                 mock.getArrayOfGenericElements(2);
1366                 result = numberValues;
1367                 mock.getArrayOfGenericElements(3);
1368                 result = stringValues;
1369             }
1370         };
1371 
1372         assertSame(numberValues, mock.getArrayOfGenericElements(2));
1373         assertSame(integerValues, mock.getArrayOfGenericElements(1));
1374         try {
1375             mock.getArrayOfGenericElements(3);
1376             fail();
1377         } catch (ClassCastException ignore) {
1378         }
1379     }
1380 
1381     /**
1382      * Creates the array from single recorded value of the element type.
1383      *
1384      * @param mock
1385      *            the mock
1386      */
1387     @Test
1388     void createArrayFromSingleRecordedValueOfTheElementType(@Mocked final Collaborator mock) {
1389         new Expectations() {
1390             {
1391                 mock.getIntArray();
1392                 result = 123;
1393                 mock.getStringArray();
1394                 result = "test";
1395             }
1396         };
1397 
1398         assertArrayEquals(new int[] { 123 }, mock.getIntArray());
1399         assertArrayEquals(new String[] { "test" }, mock.getStringArray());
1400     }
1401 
1402     /**
1403      * Creates the appropriate container from single recorded value of the element type.
1404      *
1405      * @param mock
1406      *            the mock
1407      */
1408     @Test
1409     void createAppropriateContainerFromSingleRecordedValueOfTheElementType(@Mocked final Collaborator mock) {
1410         final Double d = 1.2;
1411         final Float f = 3.45F;
1412         final BigDecimal price = new BigDecimal("123.45");
1413 
1414         new Expectations() {
1415             {
1416                 mock.getNumbers();
1417                 result = 123;
1418                 mock.getNumberList();
1419                 result = 45L;
1420                 mock.getStringSet();
1421                 result = "test";
1422                 mock.getSortedNumberSet();
1423                 result = d;
1424                 mock.getNumberIterable();
1425                 result = price;
1426                 mock.getNumberQueue();
1427                 result = d;
1428                 mock.getStringIterator();
1429                 result = "Abc";
1430                 mock.getFloatIterator();
1431                 result = f;
1432             }
1433         };
1434 
1435         assertContainerWithSingleElement(mock.getNumbers(), 123);
1436         assertContainerWithSingleElement(mock.getNumberList(), 45L);
1437         assertContainerWithSingleElement(mock.getStringSet(), "test");
1438         assertContainerWithSingleElement(mock.getSortedNumberSet(), d);
1439         assertContainerWithSingleElement(mock.getNumberIterable(), price);
1440         assertContainerWithSingleElement(mock.getNumberQueue(), d);
1441         assertContainerWithSingleElement(mock.getStringIterator(), "Abc");
1442         assertContainerWithSingleElement(mock.getFloatIterator(), f);
1443     }
1444 
1445     /**
1446      * Assert container with single element.
1447      *
1448      * @param container
1449      *            the container
1450      * @param expectedElement
1451      *            the expected element
1452      */
1453     void assertContainerWithSingleElement(Iterable<?> container, Object expectedElement) {
1454         assertContainerWithSingleElement(container.iterator(), expectedElement);
1455     }
1456 
1457     /**
1458      * Assert container with single element.
1459      *
1460      * @param container
1461      *            the container
1462      * @param expectedElement
1463      *            the expected element
1464      */
1465     void assertContainerWithSingleElement(Iterator<?> container, Object expectedElement) {
1466         assertTrue(container.hasNext());
1467         assertSame(expectedElement, container.next());
1468         assertFalse(container.hasNext());
1469     }
1470 }