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