1
2
3
4
5
6 package mockit;
7
8 import static java.util.Arrays.asList;
9 import static java.util.Collections.singletonList;
10
11 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
12 import static org.junit.jupiter.api.Assertions.assertEquals;
13 import static org.junit.jupiter.api.Assertions.assertFalse;
14 import static org.junit.jupiter.api.Assertions.assertNull;
15 import static org.junit.jupiter.api.Assertions.assertSame;
16 import static org.junit.jupiter.api.Assertions.assertThrows;
17 import static org.junit.jupiter.api.Assertions.assertTrue;
18
19 import java.math.BigInteger;
20 import java.util.ArrayList;
21 import java.util.LinkedList;
22 import java.util.List;
23
24 import mockit.integration.junit5.JMockitExtension;
25 import mockit.internal.expectations.invocation.MissingInvocation;
26
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.api.extension.ExtendWith;
29
30
31
32
33 @ExtendWith(JMockitExtension.class)
34 @SuppressWarnings("ConstantConditions")
35 class WithCaptureTest {
36
37
38
39
40 public static class Person {
41
42
43 private String name;
44
45
46 private int age;
47
48
49
50
51 public Person() {
52 }
53
54
55
56
57
58
59
60
61
62 public Person(String name, int age) {
63 this.name = name;
64 this.age = age;
65 }
66
67
68
69
70
71
72 public String getName() {
73 return name;
74 }
75
76
77
78
79
80
81 public int getAge() {
82 return age;
83 }
84 }
85
86
87
88
89
90
91
92 public interface DAO<T> {
93
94
95
96
97
98
99 @SuppressWarnings("unused")
100 void create(T t);
101 }
102
103
104
105
106 @SuppressWarnings("UnusedParameters")
107 public static final class PersonDAO implements DAO<Person> {
108 @Override
109 public void create(Person p) {
110 }
111
112
113
114
115
116
117
118
119
120
121
122 public Person create(String name, int age) {
123 return new Person(name, age);
124 }
125
126
127
128
129
130
131
132 public void doSomething(Integer i) {
133 }
134
135
136
137
138
139
140
141 public void doSomething(boolean b) {
142 }
143
144
145
146
147
148
149
150 public void doSomething(Number n) {
151 }
152
153
154
155
156
157
158
159 public void doSomethingElse(Number n) {
160 }
161
162
163
164
165
166
167
168 public void doSomething(Number[] nums) {
169 }
170
171
172
173
174
175
176
177 public void doSomething(List<Integer> nums) {
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 public void doSomething(String s1, boolean b, String s2, double d, float f, long l, Object o, char c, byte bt,
205 short sh) {
206 }
207
208
209
210
211
212
213
214
215
216 void doSomething(String[] names, int[] ages) {
217 }
218
219
220
221
222
223
224
225
226
227
228
229 void doSomething(Float f1, float f2, boolean... flags) {
230 }
231
232
233
234
235
236
237
238
239
240 void doSomething(String name, Short age) {
241 }
242 }
243
244
245 @Mocked
246 PersonDAO dao;
247
248
249
250
251 @Test
252 void captureArgumentFromLastMatchingInvocationToLocalVariable() {
253 dao.create("Mary Jane", 10);
254 dao.create("John", 25);
255
256 new FullVerifications() {
257 {
258 int age;
259 dao.create(null, age = withCapture());
260 assertTrue(age >= 18);
261 }
262 };
263 }
264
265
266
267
268 @Test
269 void captureArgumentOfWrapperTypeToLocalVariableOfPrimitiveType() {
270 dao.doSomething(45);
271
272 new Verifications() {
273 {
274 int i;
275 dao.doSomething(i = withCapture());
276 assertEquals(45, i);
277 }
278 };
279 }
280
281
282
283
284 @Test
285 void captureNullArgumentOfWrapperTypeToLocalVariableOfSameWrapperType() {
286 dao.doSomething((Integer) null);
287
288 new Verifications() {
289 {
290 Integer i;
291 dao.doSomething(i = withCapture());
292 assertNull(i);
293 }
294 };
295 }
296
297
298
299
300 @Test
301 void captureArgumentOfReferenceTypeToLocalVariableOfPrimitiveType() {
302 dao.doSomething(123.0F);
303
304 new Verifications() {
305 {
306 float f;
307 dao.doSomething(f = withCapture());
308 assertEquals(123.0F, f, 0);
309 }
310 };
311 }
312
313
314
315
316 @Test
317 void captureNullIntoAListDuringVerification() {
318 dao.create(null);
319
320 new Verifications() {
321 {
322 List<Person> persons = new ArrayList<>();
323 dao.create(withCapture(persons));
324 assertEquals(1, persons.size());
325 assertNull(persons.get(0));
326 }
327 };
328 }
329
330
331
332
333 @Test
334 void captureArgumentToVariableOfSpecificSubtypeForSeparateInvocations() {
335 dao.doSomething(new BigInteger("9999"));
336 dao.doSomething((byte) -123);
337 dao.doSomething(123.0F);
338 dao.doSomething(1234L);
339 dao.doSomething(1234.5);
340
341 new Verifications() {
342 {
343 BigInteger bi;
344 dao.doSomething(bi = withCapture());
345 assertEquals(9999, bi.intValue());
346
347 Float f;
348 dao.doSomething(f = withCapture());
349 assertEquals(123.0F, f, 0);
350
351 long l;
352 dao.doSomething(l = withCapture());
353 assertEquals(1234L, l);
354
355 Double d;
356 dao.doSomething(d = withCapture());
357 assertEquals(1234.5, d, 0);
358
359 byte b;
360 dao.doSomething(b = withCapture());
361 assertEquals(-123, b);
362 }
363 };
364 }
365
366
367
368
369 @Test
370 void captureArrayArgumentsToVariablesWithSpecificElementSubtypes() {
371 final Integer[] ints = { 1, 2, 3 };
372 dao.doSomething(ints);
373
374 final Double[] doubles = { 1.0, 2.5, -3.2 };
375 dao.doSomething(doubles);
376
377 final BigInteger[] bigInts = { new BigInteger("12"), new BigInteger("45") };
378 dao.doSomething(bigInts);
379
380 new VerificationsInOrder() {
381 {
382 Integer[] capturedInts;
383 dao.doSomething(capturedInts = withCapture());
384 assertSame(ints, capturedInts);
385
386 Double[] capturedDoubles;
387 dao.doSomething(capturedDoubles = withCapture());
388 assertSame(doubles, capturedDoubles);
389
390 BigInteger[] capturedBigInts;
391 dao.doSomething(capturedBigInts = withCapture());
392 assertSame(bigInts, capturedBigInts);
393 }
394 };
395 }
396
397
398
399
400 @Test
401 void captureArgumentOfPrimitiveTypeToLocalVariableOfPrimitiveType() {
402 dao.doSomething(true);
403
404 new Verifications() {
405 {
406 boolean b;
407 dao.doSomething(b = withCapture());
408 assertTrue(b);
409 }
410 };
411 }
412
413
414
415
416 @Test
417 void captureArgumentOfPrimitiveTypeToLocalVariableOfReferenceType() {
418 dao.doSomething(true);
419
420 new Verifications() {
421 {
422 Boolean b;
423 dao.doSomething(b = withCapture());
424 assertTrue(b);
425 }
426 };
427 }
428
429
430
431
432 @Test
433 void captureArgumentsToLocalVariables() {
434 final Person p = new Person("John", 10);
435 dao.create(p);
436 dao.create("Mary Jane", 30);
437 dao.doSomething("test", true, "Test", 4.5, -2.3F, 123, p, 'g', (byte) 127, (short) -32767);
438
439 new Verifications() {
440 {
441 Person created;
442 dao.create(created = withCapture());
443 assertEquals("John", created.getName());
444 assertEquals(10, created.getAge());
445
446 String name;
447 int age;
448 dao.create(name = withCapture(), age = withCapture());
449 assertEquals("Mary Jane", name);
450 assertEquals(30, age);
451
452 String s1;
453 boolean b;
454 double d;
455 float f;
456 long l;
457 Object o;
458 char c;
459 byte bt;
460 short sh;
461 dao.doSomething(s1 = withCapture(), b = withCapture(), "Test", d = withCapture(), f = withCapture(),
462 l = withCapture(), o = withCapture(), c = withCapture(), bt = withCapture(),
463 sh = withCapture());
464 assertEquals("test", s1);
465 assertTrue(b);
466 assertEquals(4.5, d, 0);
467 assertEquals(-2.3, f, 0.001);
468 assertEquals(123, l);
469 assertSame(p, o);
470 assertEquals('g', c);
471 assertEquals(127, bt);
472 assertEquals(-32767, sh);
473 }
474 };
475 }
476
477
478
479
480 @Test
481 void attemptToCaptureArgumentsIntoFields() {
482 dao.doSomething(56);
483
484 new Verifications() {
485 final Integer i;
486
487 {
488 dao.doSomething(i = withCapture());
489 assertNull(i);
490 }
491 };
492 }
493
494
495
496
497 @Test
498 void captureFirstArgumentInTwoParameterMethod() {
499 final String name1 = "Ted";
500 final Short age = 15;
501 dao.doSomething(name1, age);
502
503 final String name2 = "Jane";
504 dao.doSomething(name2, age);
505
506 new VerificationsInOrder() {
507 {
508 String nameCapture;
509 dao.doSomething(nameCapture = withCapture(), age);
510 assertEquals(name1, nameCapture);
511
512 String strCapture;
513 dao.doSomething(strCapture = withCapture(), age);
514 assertEquals(name2, strCapture);
515 }
516 };
517 }
518
519
520
521
522 @Test
523 void captureArgumentsForInvocationAlreadyMatchedByRecordedExpectation() {
524 new Expectations() {
525 {
526 dao.doSomething(anyString, anyShort);
527 }
528 };
529
530 dao.doSomething("testing", (short) 15);
531
532 new Verifications() {
533 {
534 String s;
535 short i;
536 dao.doSomething(s = withCapture(), i = withCapture());
537 assertEquals("testing", s);
538 assertEquals(15, i);
539 }
540 };
541 }
542
543
544
545
546 @Test
547 void captureArgumentsFromConsecutiveMatchingInvocations() {
548 dao.doSomething((byte) 56);
549 dao.doSomething(123.4F);
550 dao.doSomething((short) -78);
551 dao.doSomething(91);
552 dao.doSomething(92);
553
554 final String[] names1 = { "Ted" };
555 final int[] ages1 = { 15, 46 };
556 dao.doSomething(names1, ages1);
557
558 final String[] names2 = { "Jane" };
559 final int[] ages2 = { 101 };
560 dao.doSomething(names2, ages2);
561
562 new VerificationsInOrder() {
563 {
564 byte bt;
565 dao.doSomething(bt = withCapture());
566 assertEquals(56, bt);
567
568 Number n;
569 dao.doSomething(n = withCapture());
570 assertEquals(123.4, n.floatValue(), 0.001);
571
572 short sh;
573 dao.doSomething(sh = withCapture());
574 assertEquals(-78, sh);
575
576 int i1;
577 dao.doSomething(i1 = withCapture());
578 assertEquals(91, i1);
579
580 Integer i2;
581 dao.doSomething(i2 = withCapture());
582 assertEquals(92, i2.intValue());
583
584 String[] namesCapture;
585 int[] agesCapture;
586 dao.doSomething(namesCapture = withCapture(), agesCapture = withCapture());
587 assertSame(names1, namesCapture);
588 assertSame(ages1, agesCapture);
589
590 dao.doSomething(namesCapture = withCapture(), agesCapture = withCapture());
591 assertSame(names2, namesCapture);
592 assertSame(ages2, agesCapture);
593 }
594 };
595 }
596
597
598
599
600 @Test
601 void captureArrayArguments() {
602 final String[] names = { "Ted", "Lisa" };
603 final int[] ages = { 67, 19 };
604 dao.doSomething(names, ages);
605
606 new Verifications() {
607 {
608 String[] capturedNames;
609 int[] capturedAges;
610 dao.doSomething(capturedNames = withCapture(), capturedAges = withCapture());
611
612 assertArrayEquals(names, capturedNames);
613 assertArrayEquals(ages, capturedAges);
614 }
615 };
616 }
617
618
619
620
621 @Test
622 void captureVarargsParameter() {
623 dao.doSomething(1.2F, 1.0F, true, false, true);
624 dao.doSomething(0.0F, 2.0F, false, true);
625 dao.doSomething(-2.0F, 3.0F);
626
627 new VerificationsInOrder() {
628 {
629 boolean[] flags;
630
631 dao.doSomething(anyFloat, 1.0F, flags = withCapture());
632 assertEquals(3, flags.length);
633 assertTrue(flags[0]);
634 assertFalse(flags[1]);
635 assertTrue(flags[2]);
636
637 dao.doSomething(null, 2.0F, flags = withCapture());
638 assertEquals(2, flags.length);
639 assertFalse(flags[0]);
640 assertTrue(flags[1]);
641
642 dao.doSomething(withAny(0.0F), 3.0F, flags = withCapture());
643 assertEquals(0, flags.length);
644 }
645 };
646 }
647
648
649
650
651 @Test
652 void captureArgumentsWhileMixingAnyFieldsAndLiteralValuesAndCallsToOtherMethods() {
653 final double d = 4.5;
654 final long l = 123;
655 dao.doSomething("Test", true, "data", d, 12.25F, l, "testing", '9', (byte) 11, (short) 5);
656
657 new Verifications() {
658 {
659 float f;
660 String s;
661 byte b;
662
663
664 dao.doSomething(null, anyBoolean, getData(), Math.abs(-d), f = withCapture(), Long.parseLong("" + l),
665 s = withCapture(), Character.forDigit(9, 10), b = withCapture(), anyShort);
666
667 assertEquals(12.25F, f, 0);
668 assertEquals("testing", s);
669 assertEquals(11, b);
670 }
671 };
672 }
673
674
675
676
677
678
679 private String getData() {
680 return "data";
681 }
682
683
684
685
686 @Test
687 void captureArgumentsIntoListInExpectationBlock() {
688 final List<Person> personsCreated = new ArrayList<>();
689 final List<String> personNames = new LinkedList<>();
690 final List<Integer> personAges = new LinkedList<>();
691
692 new Expectations() {
693 {
694 dao.create(withCapture(personsCreated));
695 dao.create(withCapture(personNames), withCapture(personAges));
696 }
697 };
698
699 dao.create(new Person("John", 10));
700 assertEquals(1, personsCreated.size());
701 Person first = personsCreated.get(0);
702 assertEquals("John", first.getName());
703 assertEquals(10, first.getAge());
704
705 dao.create(new Person("Jane", 20));
706 assertEquals(2, personsCreated.size());
707 Person second = personsCreated.get(1);
708 assertEquals("Jane", second.getName());
709 assertEquals(20, second.getAge());
710
711 dao.create("Mary Jane", 35);
712 assertEquals(1, personNames.size());
713 assertEquals("Mary Jane", personNames.get(0));
714 assertEquals(1, personAges.size());
715 assertEquals(35, personAges.get(0).intValue());
716 }
717
718
719
720
721 @Test
722 void captureArgumentsIntoListInVerificationBlock() {
723 dao.create(new Person("John", 10));
724 dao.create("Mary Jane", 35);
725 dao.create("", 56);
726 dao.create(new Person("Jane", 20));
727 dao.create("Daisy Jones", 6);
728
729 new Verifications() {
730 final List<Person> created = new ArrayList<>();
731 final List<Integer> ages = new ArrayList<>();
732
733 {
734 dao.create("", withCapture(ages));
735 assertEquals(singletonList(56), ages);
736
737 dao.create(withCapture(created));
738 assertEquals(2, created.size());
739
740 Person first = created.get(0);
741 assertEquals("John", first.getName());
742 assertEquals(10, first.getAge());
743
744 Person second = created.get(1);
745 assertEquals("Jane", second.getName());
746 assertEquals(20, second.getAge());
747
748 ages.clear();
749 dao.create(withSubstring(" "), withCapture(ages));
750 times = 2;
751 assertEquals(asList(35, 6), ages);
752 }
753 };
754 }
755
756
757
758
759
760
761
762 @Test
763 void captureNewedInstance(@Mocked Person mockedPerson) {
764 Person p = new Person();
765 dao.create(p);
766
767 new Verifications() {
768 {
769 Person newInstance = withCapture(new Person()).get(0);
770
771 Person capturedPerson;
772 dao.create(capturedPerson = withCapture());
773
774 assertSame(newInstance, capturedPerson);
775 }
776 };
777 }
778
779
780
781
782
783
784
785 @Test
786 void captureMultipleNewInstances(@Mocked Person mockedPerson) {
787 dao.create(new Person("Paul", 10));
788 dao.create(new Person("Mary", 15));
789 dao.create(new Person("Joe", 20));
790
791 new Verifications() {
792 {
793 List<Person> personsInstantiated = withCapture(new Person(anyString, anyInt));
794
795 List<Person> personsCreated = new ArrayList<>();
796 dao.create(withCapture(personsCreated));
797
798
799 assertEquals(personsInstantiated, personsCreated);
800 }
801 };
802 }
803
804
805
806
807
808
809
810 @Test
811 void attemptToCaptureNewInstanceWhenThereWasNone(@Mocked Person mockedPerson) {
812 Throwable exception = assertThrows(MissingInvocation.class, () -> {
813
814 dao.create("test", 14);
815
816 new Verifications() {
817 {
818 List<Person> newInstances = withCapture(new Person());
819 times = 0;
820 assertTrue(newInstances.isEmpty());
821
822 withCapture(new Person(anyString, anyInt));
823 }
824 };
825 });
826 assertTrue(exception.getMessage().contains("Person(any String, any int)"));
827 }
828
829
830
831
832
833
834
835 @Test
836 void captureTwoSetsOfNewInstancesOfTheSameType(@Mocked Person mockedPerson) {
837
838 final Person p1 = new Person();
839
840
841 final Person p2 = new Person("Paul", 10);
842 final Person p3 = new Person("Mary", 15);
843
844 new Verifications() {
845 {
846 List<Person> persons1 = withCapture(new Person(anyString, anyInt));
847 assertEquals(asList(p2, p3), persons1);
848
849 List<Person> persons2 = withCapture(new Person());
850 assertEquals(singletonList(p1), persons2);
851 }
852 };
853 }
854
855
856
857
858
859
860
861 @Test
862 void captureNewInstancesAfterVerifyingNewInstanceOfDifferentType(@Mocked Person mockedPerson) {
863 new PersonDAO();
864 final Person p1 = new Person("Paul", 10);
865 final Person p2 = new Person("Mary", 10);
866
867 new Verifications() {
868 {
869 new PersonDAO();
870
871 List<Person> persons = withCapture(new Person(anyString, 10));
872 assertEquals(asList(p1, p2), persons);
873 }
874 };
875 }
876
877
878
879
880 @Test
881 void attemptToCaptureArgumentForInvocationThatNeverOccurred_unordered() {
882 Throwable exception = assertThrows(MissingInvocation.class, () -> {
883
884 new Verifications() {
885 {
886 Person p;
887 dao.create(p = withCapture());
888 times = 1;
889 assertEquals("...", p.getName());
890 }
891 };
892 });
893 assertTrue(exception.getMessage().contains("any " + Person.class.getName()));
894 }
895
896
897
898
899 @Test
900 void attemptToCaptureArgumentForInvocationThatNeverOccurred_ordered() {
901 assertThrows(MissingInvocation.class, () -> {
902
903 new VerificationsInOrder() {
904 {
905 Person p;
906 dao.create(p = withCapture());
907 times = 1;
908 assertEquals("...", p.getName());
909 }
910 };
911 });
912 }
913
914
915
916
917 static class ClassWithVarargsMethod {
918
919
920
921
922
923
924
925
926 @SuppressWarnings("unused")
927 void varargsMethod(String s, String... values) {
928 }
929 }
930
931
932
933
934
935
936
937 @Test
938 void captureVarargsValuesFromAllInvocations(@Mocked final ClassWithVarargsMethod mock) {
939 final String[] expectedValues1 = { "a", "b" };
940 mock.varargsMethod("First", expectedValues1);
941
942 final String[] expectedValues2 = { "1", "2" };
943 mock.varargsMethod("Second", expectedValues2);
944
945 new Verifications() {
946 {
947 List<String> capturedNames = new ArrayList<>();
948 List<String[]> capturedValues = new ArrayList<>();
949
950 mock.varargsMethod(withCapture(capturedNames), withCapture(capturedValues));
951
952 assertEquals(asList("First", "Second"), capturedNames);
953 assertArrayEquals(expectedValues1, capturedValues.get(0));
954 assertArrayEquals(expectedValues2, capturedValues.get(1));
955 }
956 };
957 }
958
959
960
961
962 @Test
963 void captureArgumentsIntoAListOfASubtypeOfTheCapturedParameterType() {
964 dao.doSomethingElse(1);
965 dao.doSomethingElse(2.0d);
966 dao.doSomethingElse(3);
967
968 final List<Integer> expectedValues = asList(1, 3);
969
970 new Verifications() {
971 {
972 List<Integer> onlyIntegers = new ArrayList<>();
973 dao.doSomethingElse(withCapture(onlyIntegers));
974
975 assertEquals(expectedValues, onlyIntegers);
976 }
977 };
978 }
979
980
981
982
983 @Test
984 void captureListArgumentsFromMultipleInvocations() {
985 final List<Integer> integers1 = asList(1, 2, 3);
986 dao.doSomething(integers1);
987
988 final List<Integer> integers2 = asList(4, 5);
989 dao.doSomething(integers2);
990
991 new Verifications() {
992 {
993 List<List<Integer>> captures = new ArrayList<>();
994 dao.doSomething(withCapture(captures));
995 assertEquals(integers1, captures.get(0));
996 assertEquals(integers2, captures.get(1));
997 }
998 };
999 }
1000 }