View Javadoc
1   package mockit;
2   
3   import static java.util.Arrays.asList;
4   
5   import static org.junit.jupiter.api.Assertions.assertEquals;
6   import static org.junit.jupiter.api.Assertions.assertFalse;
7   import static org.junit.jupiter.api.Assertions.assertThrows;
8   import static org.junit.jupiter.api.Assertions.assertTrue;
9   
10  import java.util.ArrayList;
11  import java.util.Date;
12  import java.util.List;
13  
14  import mockit.internal.expectations.invocation.MissingInvocation;
15  
16  import org.junit.jupiter.api.Test;
17  
18  /**
19   * The Class ExpectationsWithSomeArgMatchersRecordedTest.
20   */
21  final class ExpectationsWithSomeArgMatchersRecordedTest {
22  
23      /**
24       * The Class Dependency.
25       */
26      static class Dependency {
27  
28          /** The value. */
29          private final int value;
30  
31          /**
32           * Instantiates a new dependency.
33           */
34          Dependency() {
35              value = 0;
36          }
37  
38          /**
39           * Instantiates a new dependency.
40           *
41           * @param value
42           *            the value
43           */
44          Dependency(int value) {
45              this.value = value;
46          }
47  
48          @Override
49          public boolean equals(Object obj) {
50              return obj instanceof Dependency && value == ((Dependency) obj).value;
51          }
52  
53          @Override
54          public int hashCode() {
55              return value;
56          }
57      }
58  
59      /**
60       * The Class Collaborator.
61       */
62      @SuppressWarnings({ "SameParameterValue", "unused" })
63      static class Collaborator {
64  
65          /**
66           * Sets the value.
67           *
68           * @param value
69           *            the new value
70           */
71          void setValue(int value) {
72          }
73  
74          /**
75           * Sets the value.
76           *
77           * @param value
78           *            the new value
79           */
80          void setValue(double value) {
81          }
82  
83          /**
84           * Sets the value.
85           *
86           * @param value
87           *            the new value
88           */
89          void setValue(float value) {
90          }
91  
92          /**
93           * Sets the value.
94           *
95           * @param value
96           *            the value
97           *
98           * @return the string
99           */
100         String setValue(String value) {
101             return "";
102         }
103 
104         /**
105          * Sets the values.
106          *
107          * @param value1
108          *            the value 1
109          * @param value2
110          *            the value 2
111          * @param value3
112          *            the value 3
113          * @param value4
114          *            the value 4
115          */
116         void setValues(long value1, byte value2, double value3, short value4) {
117         }
118 
119         /**
120          * Boolean values.
121          *
122          * @param value1
123          *            the value 1
124          * @param value2
125          *            the value 2
126          * @param value3
127          *            the value 3
128          * @param value4
129          *            the value 4
130          *
131          * @return true, if successful
132          */
133         boolean booleanValues(long value1, byte value2, double value3, short value4) {
134             return true;
135         }
136 
137         /**
138          * Static set values.
139          *
140          * @param value1
141          *            the value 1
142          * @param value2
143          *            the value 2
144          * @param value3
145          *            the value 3
146          * @param value4
147          *            the value 4
148          */
149         static void staticSetValues(long value1, byte value2, double value3, short value4) {
150         }
151 
152         /**
153          * Static long values.
154          *
155          * @param value1
156          *            the value 1
157          * @param value2
158          *            the value 2
159          * @param value3
160          *            the value 3
161          * @param value4
162          *            the value 4
163          *
164          * @return the long
165          */
166         static long staticLongValues(long value1, byte value2, double value3, short value4) {
167             return -2;
168         }
169 
170         /**
171          * Do something.
172          *
173          * @param src
174          *            the src
175          *
176          * @return the int
177          */
178         int doSomething(Dependency src) {
179             return -1;
180         }
181 
182         /**
183          * Do something.
184          *
185          * @param src
186          *            the src
187          * @param s
188          *            the s
189          *
190          * @return the int
191          */
192         int doSomething(Dependency src, String s) {
193             return -1;
194         }
195 
196         /**
197          * Do something.
198          *
199          * @param src
200          *            the src
201          * @param s
202          *            the s
203          *
204          * @return the int
205          */
206         int doSomething(Dependency src, String... s) {
207             return -1;
208         }
209 
210         /**
211          * Simple operation.
212          *
213          * @param a
214          *            the a
215          * @param b
216          *            the b
217          */
218         final void simpleOperation(int a, String b) {
219         }
220 
221         /**
222          * Simple operation.
223          *
224          * @param a
225          *            the a
226          * @param b
227          *            the b
228          * @param c
229          *            the c
230          */
231         final void simpleOperation(int a, String b, Date c) {
232         }
233 
234         /**
235          * Another operation.
236          *
237          * @param b
238          *            the b
239          * @param l
240          *            the l
241          *
242          * @return the long
243          */
244         long anotherOperation(byte b, Long l) {
245             return -1;
246         }
247 
248         /**
249          * Static void method.
250          *
251          * @param l
252          *            the l
253          * @param c
254          *            the c
255          * @param d
256          *            the d
257          */
258         static void staticVoidMethod(long l, char c, double d) {
259         }
260 
261         /**
262          * Static boolean method.
263          *
264          * @param b
265          *            the b
266          * @param s
267          *            the s
268          * @param array
269          *            the array
270          *
271          * @return true, if successful
272          */
273         static boolean staticBooleanMethod(boolean b, String s, int[] array) {
274             return false;
275         }
276 
277         /**
278          * Method with array parameters.
279          *
280          * @param c
281          *            the c
282          * @param s
283          *            the s
284          * @param matrix
285          *            the matrix
286          */
287         void methodWithArrayParameters(char[][] c, String[] s, Object[][][] matrix) {
288         }
289 
290         /**
291          * Method with many parameters.
292          *
293          * @param b1
294          *            the b 1
295          * @param s1
296          *            the s 1
297          * @param i1
298          *            the i 1
299          * @param l1
300          *            the l 1
301          * @param str1
302          *            the str 1
303          * @param bo1
304          *            the bo 1
305          * @param f1
306          *            the f 1
307          * @param d1
308          *            the d 1
309          * @param ii1
310          *            the ii 1
311          * @param ss1
312          *            the ss 1
313          * @param b2
314          *            the b 2
315          * @param s2
316          *            the s 2
317          * @param i2
318          *            the i 2
319          * @param l2
320          *            the l 2
321          * @param str2
322          *            the str 2
323          * @param bo2
324          *            the bo 2
325          * @param f2
326          *            the f 2
327          * @param d2
328          *            the d 2
329          * @param ii2
330          *            the ii 2
331          * @param ss2
332          *            the ss 2
333          * @param c
334          *            the c
335          */
336         void methodWithManyParameters(byte b1, short s1, int i1, long l1, String str1, boolean bo1, float f1, double d1,
337                 int[] ii1, String[] ss1, byte b2, short s2, int i2, long l2, String str2, boolean bo2, float f2,
338                 double d2, int[] ii2, String[] ss2, char c) {
339         }
340     }
341 
342     /** The mock. */
343     @Mocked
344     Collaborator mock;
345 
346     /**
347      * Use matcher only for one argument.
348      */
349     @Test
350     void useMatcherOnlyForOneArgument() {
351         final Object o = new Object();
352 
353         new Expectations() {
354             {
355                 mock.simpleOperation(withEqual(1), "", null);
356                 mock.simpleOperation(withNotEqual(1), null, (Date) withNull());
357                 mock.simpleOperation(12, "arg", (Date) withNotNull());
358 
359                 mock.anotherOperation((byte) 0, anyLong);
360                 result = 123L;
361                 mock.anotherOperation(anyByte, 5L);
362                 result = -123L;
363 
364                 Collaborator.staticVoidMethod(34L, anyChar, 5.0);
365                 Collaborator.staticBooleanMethod(true, withSuffix("end"), null);
366                 result = true;
367                 Collaborator.staticBooleanMethod(true, "", new int[] { 1, 2, 3 });
368                 result = true;
369 
370                 char[][] chars = { { 'a', 'b' }, { 'X', 'Y', 'Z' } };
371                 Object[][][] matrix = { null, { { 1, 'X', "test" } }, { { o } } };
372                 mock.methodWithArrayParameters(chars, (String[]) any, matrix);
373             }
374         };
375 
376         mock.simpleOperation(1, "", null);
377         mock.simpleOperation(2, "str", null);
378         mock.simpleOperation(1, "", null);
379         mock.simpleOperation(12, "arg", new Date());
380 
381         assertEquals(123L, mock.anotherOperation((byte) 0, 5L));
382         assertEquals(-123L, mock.anotherOperation((byte) 3, 5L));
383 
384         Collaborator.staticVoidMethod(34L, '8', 5.0);
385         assertTrue(Collaborator.staticBooleanMethod(true, "start-end", null));
386         assertTrue(Collaborator.staticBooleanMethod(true, "", new int[] { 1, 2, 3 }));
387 
388         mock.methodWithArrayParameters(new char[][] { { 'a', 'b' }, { 'X', 'Y', 'Z' } }, null,
389                 new Object[][][] { null, { { 1, 'X', "test" } }, { { o } } });
390     }
391 
392     /**
393      * Use matcher only for first argument with unexpected replay value.
394      */
395     @Test
396     void useMatcherOnlyForFirstArgumentWithUnexpectedReplayValue() {
397         assertThrows(MissingInvocation.class, () -> {
398 
399             mock.simpleOperation(2, "", null);
400 
401             new Verifications() {
402                 {
403                     mock.simpleOperation(withEqual(1), "", null);
404                 }
405             };
406         });
407     }
408 
409     /**
410      * Use matcher only for second argument with unexpected replay value.
411      */
412     @Test
413     void useMatcherOnlyForSecondArgumentWithUnexpectedReplayValue() {
414         assertThrows(MissingInvocation.class, () -> {
415 
416             mock.simpleOperation(1, "Xyz", null);
417 
418             new Verifications() {
419                 {
420                     mock.simpleOperation(1, withPrefix("arg"), null);
421                 }
422             };
423         });
424     }
425 
426     /**
427      * Use matcher only for last argument with unexpected replay value.
428      */
429     @Test
430     void useMatcherOnlyForLastArgumentWithUnexpectedReplayValue() {
431         assertThrows(MissingInvocation.class, () -> {
432 
433             mock.simpleOperation(12, "arg", null);
434 
435             new Verifications() {
436                 {
437                     mock.simpleOperation(12, "arg", (Date) withNotNull());
438                 }
439             };
440         });
441     }
442 
443     /**
444      * Use matchers for parameters of all sizes.
445      */
446     @Test
447     void useMatchersForParametersOfAllSizes() {
448         new Expectations() {
449             {
450                 mock.setValues(123L, withEqual((byte) 5), 6.4, withNotEqual((short) 14));
451                 mock.booleanValues(12L, (byte) 4, withEqual(6.0, 0.1), withEqual((short) 14));
452                 Collaborator.staticSetValues(withNotEqual(1L), (byte) 4, 6.1, withEqual((short) 3));
453                 Collaborator.staticLongValues(12L, anyByte, withEqual(6.1), (short) 4);
454             }
455         };
456 
457         mock.setValues(123L, (byte) 5, 6.4, (short) 41);
458         assertFalse(mock.booleanValues(12L, (byte) 4, 6.1, (short) 14));
459         Collaborator.staticSetValues(2L, (byte) 4, 6.1, (short) 3);
460         assertEquals(0L, Collaborator.staticLongValues(12L, (byte) -7, 6.1, (short) 4));
461     }
462 
463     /**
464      * Use any int field.
465      */
466     @Test
467     void useAnyIntField() {
468         new Expectations() {
469             {
470                 mock.setValue(anyInt);
471             }
472         };
473 
474         mock.setValue(1);
475     }
476 
477     /**
478      * Use any string field.
479      */
480     @Test
481     void useAnyStringField() {
482         new Expectations() {
483             {
484                 mock.setValue(anyString);
485                 returns("one", "two");
486             }
487         };
488 
489         assertEquals("one", mock.setValue("test"));
490         assertEquals("two", mock.setValue(""));
491         assertEquals("two", mock.setValue(null));
492     }
493 
494     /**
495      * Use several any fields.
496      */
497     @Test
498     void useSeveralAnyFields() {
499         final Date now = new Date();
500 
501         new Expectations() {
502             {
503                 mock.simpleOperation(anyInt, null, null);
504                 mock.simpleOperation(anyInt, "test", null);
505                 mock.simpleOperation(3, "test2", null);
506                 mock.simpleOperation(-1, null, (Date) any);
507                 mock.simpleOperation(1, anyString, now);
508 
509                 Collaborator.staticSetValues(2L, anyByte, 0.0, anyShort);
510 
511                 // noinspection ConstantConditions
512                 mock.methodWithManyParameters(anyByte, anyShort, anyInt, anyLong, anyString, anyBoolean, anyFloat,
513                         anyDouble, (int[]) any, (String[]) any, anyByte, anyShort, anyInt, anyLong, anyString,
514                         anyBoolean, anyFloat, anyDouble, (int[]) any, (String[]) any, anyChar);
515             }
516         };
517 
518         mock.simpleOperation(2, "abc", now);
519         mock.simpleOperation(5, "test", null);
520         mock.simpleOperation(3, "test2", null);
521         mock.simpleOperation(-1, "Xyz", now);
522         mock.simpleOperation(1, "", now);
523 
524         Collaborator.staticSetValues(2, (byte) 1, 0, (short) 2);
525 
526         mock.methodWithManyParameters((byte) 1, (short) 2, 3, 4L, "5", false, 7.0F, 8.0, null, null, (byte) 10,
527                 (short) 20, 30, 40L, "50", true, 70.0F, 80.0, null, null, 'x');
528     }
529 
530     /**
531      * Use with methods mixed with any fields.
532      */
533     @Test
534     void useWithMethodsMixedWithAnyFields() {
535         mock.simpleOperation(2, "abc", new Date());
536         mock.simpleOperation(5, "test", null);
537         mock.simpleOperation(3, "test2", null);
538         mock.simpleOperation(-1, "Xyz", new Date());
539         mock.simpleOperation(1, "", new Date());
540 
541         new FullVerifications() {
542             {
543                 mock.simpleOperation(anyInt, null, (Date) any);
544                 mock.simpleOperation(anyInt, withEqual("test"), null);
545                 mock.simpleOperation(3, withPrefix("test"), (Date) any);
546                 mock.simpleOperation(-1, anyString, (Date) any);
547                 mock.simpleOperation(1, anyString, (Date) withNotNull());
548             }
549         };
550     }
551 
552     /**
553      * The Interface Scheduler.
554      */
555     public interface Scheduler {
556         /**
557          * Gets the alerts.
558          *
559          * @param o
560          *            the o
561          * @param i
562          *            the i
563          * @param b
564          *            the b
565          *
566          * @return the alerts
567          */
568         List<String> getAlerts(Object o, int i, boolean b);
569     }
570 
571     /**
572      * Use matchers in invocations to interface methods.
573      *
574      * @param scheduler
575      *            the scheduler
576      */
577     @Test
578     void useMatchersInInvocationsToInterfaceMethods(@Mocked final Scheduler scheduler) {
579         new Expectations() {
580             {
581                 scheduler.getAlerts(any, 1, anyBoolean);
582                 result = asList("A", "b");
583             }
584         };
585 
586         assertEquals(2, scheduler.getAlerts("123", 1, true).size());
587     }
588 
589     // Tests for the matching of expectations to instances created during replay
590     // ///////////////////////////////////////////////////////////
591 
592     /**
593      * Record expectations for mocked objects instantiated inside SUT.
594      *
595      * @param dep
596      *            the dep
597      */
598     @Test
599     void recordExpectationsForMockedObjectsInstantiatedInsideSUT(@Mocked Dependency dep) {
600         new Expectations() {
601             {
602                 Dependency src1 = new Dependency(1);
603                 Dependency src2 = new Dependency(2);
604                 mock.doSomething(src1);
605                 result = 1;
606                 times = 2;
607                 mock.doSomething(src2);
608                 result = 2;
609                 times = 2;
610             }
611         };
612 
613         Dependency src1 = new Dependency(1);
614         Dependency src2 = new Dependency(2);
615         Dependency src3 = new Dependency(1);
616         Dependency src4 = new Dependency(2);
617 
618         assertEquals(1, mock.doSomething(src1));
619         assertEquals(2, mock.doSomething(src2));
620         assertEquals(1, mock.doSomething(src3));
621         assertEquals(2, mock.doSomething(src4));
622     }
623 
624     /**
625      * Verify unordered expectations for mocked objects instantiated inside SUT.
626      */
627     @Test
628     void verifyUnorderedExpectationsForMockedObjectsInstantiatedInsideSUT() {
629         Dependency src1 = new Dependency(1);
630         Dependency src2 = new Dependency(2);
631         Dependency src3 = new Dependency(1);
632         Dependency src4 = new Dependency(2);
633 
634         mock.doSomething(src1);
635         mock.doSomething(src2);
636         mock.doSomething(src3);
637         mock.doSomething(src4);
638 
639         final List<Dependency> dependencies = new ArrayList<>();
640         new Verifications() {
641             {
642                 mock.doSomething(withCapture(dependencies));
643                 times = 4;
644             }
645         };
646 
647         int i1 = dependencies.indexOf(new Dependency(1));
648         int l1 = dependencies.lastIndexOf(new Dependency(1));
649         assertTrue(i1 >= 0);
650         assertTrue(l1 >= 0 && l1 != i1);
651 
652         int i2 = dependencies.indexOf(new Dependency(2));
653         int l2 = dependencies.lastIndexOf(new Dependency(2));
654         assertTrue(i2 >= 0);
655         assertTrue(l2 >= 0 && l2 != i2);
656     }
657 
658     /**
659      * Verify ordered expectations for mocked objects instantiated inside SUT.
660      */
661     @Test
662     void verifyOrderedExpectationsForMockedObjectsInstantiatedInsideSUT() {
663         Dependency src1 = new Dependency(1);
664         Dependency src2 = new Dependency(2);
665         Dependency src3 = new Dependency(2);
666         Dependency src4 = new Dependency(1);
667 
668         mock.doSomething(src1);
669         mock.doSomething(src2);
670         mock.doSomething(src3);
671         mock.doSomething(src4);
672 
673         new VerificationsInOrder() {
674             {
675                 Dependency dep1 = new Dependency(1);
676                 Dependency dep2 = new Dependency(2);
677                 mock.doSomething(dep1);
678                 mock.doSomething(dep2);
679                 times = 2;
680                 mock.doSomething(dep1);
681             }
682         };
683     }
684 
685     /**
686      * Record expectation with matcher and regular argument matching mocked object instantiated inside SUT.
687      *
688      * @param dep
689      *            the dep
690      */
691     @Test
692     void recordExpectationWithMatcherAndRegularArgumentMatchingMockedObjectInstantiatedInsideSUT(
693             @Mocked Dependency dep) {
694         final List<Dependency> dependencies = new ArrayList<>();
695 
696         new Expectations() {
697             {
698                 Dependency src = new Dependency();
699                 dependencies.add(src);
700             }
701         };
702 
703         new Expectations() {
704             {
705                 Dependency firstDep = dependencies.get(0);
706                 mock.doSomething(firstDep, anyString);
707                 result = 123;
708             }
709         };
710 
711         Dependency src = new Dependency();
712         int i = mock.doSomething(src, "test");
713 
714         assertEquals(123, i);
715     }
716 
717     /**
718      * Record varargs expectation with matcher and regular argument matching mocked object instantiated inside SUT.
719      *
720      * @param dep
721      *            the dep
722      */
723     @Test
724     void recordVarargsExpectationWithMatcherAndRegularArgumentMatchingMockedObjectInstantiatedInsideSUT(
725             @Mocked Dependency dep) {
726         final List<Dependency> dependencies = new ArrayList<>();
727 
728         new Expectations() {
729             {
730                 Dependency src = new Dependency();
731                 dependencies.add(src);
732             }
733         };
734 
735         new Expectations() {
736             {
737                 Dependency firstDep = dependencies.get(0);
738                 mock.doSomething(firstDep, (String[]) any);
739                 result = 123;
740             }
741         };
742 
743         Dependency src = new Dependency();
744         int i = mock.doSomething(src, "a", "b");
745 
746         assertEquals(123, i);
747     }
748 
749     /**
750      * Record instantiation expectations for mocked objects instantiated inside SUT.
751      *
752      * @param anyDep
753      *            the any dep
754      */
755     @Test
756     void recordInstantiationExpectationsForMockedObjectsInstantiatedInsideSUT(@Mocked Dependency anyDep) {
757         new Expectations() {
758             {
759                 Dependency dep1 = new Dependency(1);
760                 Dependency dep2 = new Dependency(2);
761                 mock.doSomething(dep1);
762                 result = 1;
763                 times = 2;
764                 mock.doSomething(dep2);
765                 result = 2;
766                 times = 2;
767             }
768         };
769 
770         Dependency src1 = new Dependency(1);
771         Dependency src2 = new Dependency(2);
772         Dependency src3 = new Dependency(1);
773         Dependency src4 = new Dependency(2);
774 
775         assertEquals(1, mock.doSomething(src1));
776         assertEquals(2, mock.doSomething(src2));
777         assertEquals(1, mock.doSomething(src3));
778         assertEquals(2, mock.doSomething(src4));
779     }
780 
781     // The following tests failed only when compiled with the Eclipse compiler
782     // /////////////////////////////////////////////////////////////
783 
784     /**
785      * Expectation with matchers spanning multiple lines.
786      */
787     @Test
788     void expectationWithMatchersSpanningMultipleLines() {
789         new Expectations() {
790             {
791                 mock.simpleOperation(1, (String) withNull());
792             }
793         };
794 
795         mock.simpleOperation(1, null);
796     }
797 
798     /**
799      * Expectation with matcher in second line and constant argument in third line.
800      */
801     @Test
802     void expectationWithMatcherInSecondLineAndConstantArgumentInThirdLine() {
803         new Expectations() {
804             {
805                 mock.simpleOperation(anyInt, "test");
806             }
807         };
808 
809         mock.simpleOperation(123, "test");
810     }
811 
812     /**
813      * Expectations with partial matchers in every combination for method with three parameters.
814      */
815     @Test
816     void expectationsWithPartialMatchersInEveryCombinationForMethodWithThreeParameters() {
817         final Date now = new Date();
818 
819         mock.simpleOperation(123, "test", null);
820         mock.simpleOperation(-2, "", now);
821         mock.simpleOperation(0, "test", now);
822         mock.simpleOperation(1, "test", null);
823         mock.simpleOperation(0, "test", null);
824         mock.simpleOperation(-3, "xyz", now);
825         mock.simpleOperation(123, null, now);
826         mock.simpleOperation(123, "", null);
827 
828         new VerificationsInOrder() {
829             {
830                 // Expectations with one matcher:
831                 mock.simpleOperation(anyInt, "test", null);
832                 mock.simpleOperation(-2, anyString, null);
833                 mock.simpleOperation(0, "test", (Date) withNotNull());
834                 mock.simpleOperation(1, null, (Date) withNull());
835                 mock.simpleOperation(0, "test", (Date) any);
836 
837                 // Expectations with two matchers:
838                 mock.simpleOperation(-3, anyString, (Date) any);
839                 mock.simpleOperation(withNotEqual(0), anyString, now);
840                 mock.simpleOperation(anyInt, "", (Date) any);
841             }
842         };
843     }
844 }