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