View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit;
7   
8   import static org.junit.jupiter.api.Assertions.assertEquals;
9   import static org.junit.jupiter.api.Assertions.assertFalse;
10  import static org.junit.jupiter.api.Assertions.assertNull;
11  import static org.junit.jupiter.api.Assertions.assertTrue;
12  
13  import mockit.integration.junit5.JMockitExtension;
14  
15  import org.junit.jupiter.api.Test;
16  import org.junit.jupiter.api.extension.ExtendWith;
17  
18  /**
19   * The Class ExpectationsWithDuplicateRecordingsTest.
20   */
21  @ExtendWith(JMockitExtension.class)
22  class ExpectationsWithDuplicateRecordingsTest {
23  
24      /**
25       * The Class Blah.
26       */
27      @SuppressWarnings({ "unused", "NumericCastThatLosesPrecision" })
28      static class Blah {
29  
30          /**
31           * Sets the value.
32           *
33           * @param value
34           *            the new value
35           */
36          void setValue(int value) {
37          }
38  
39          /**
40           * Do something.
41           *
42           * @param b
43           *            the b
44           *
45           * @return the string
46           */
47          String doSomething(boolean b) {
48              return "";
49          }
50  
51          /**
52           * Do something.
53           *
54           * @param s
55           *            the s
56           *
57           * @return the string
58           */
59          String doSomething(String s) {
60              return "";
61          }
62  
63          /**
64           * Do something.
65           *
66           * @param l
67           *            the l
68           *
69           * @return the long
70           */
71          long doSomething(Long l) {
72              return -1L;
73          }
74  
75          /**
76           * Do something.
77           *
78           * @param l
79           *            the l
80           * @param o
81           *            the o
82           *
83           * @return the long
84           */
85          long doSomething(Long l, Object o) {
86              return 1L;
87          }
88  
89          /**
90           * Truncate.
91           *
92           * @param d
93           *            the d
94           *
95           * @return the int
96           */
97          int truncate(double d) {
98              return (int) d;
99          }
100 
101         /**
102          * Truncate.
103          *
104          * @param f
105          *            the f
106          *
107          * @return the int
108          */
109         int truncate(float f) {
110             return (int) f;
111         }
112 
113         /**
114          * Do something.
115          *
116          * @param i
117          *            the i
118          *
119          * @return the boolean
120          */
121         Boolean doSomething(int i) {
122             return true;
123         }
124 
125         /**
126          * Do something.
127          *
128          * @param c
129          *            the c
130          *
131          * @return the int
132          */
133         int doSomething(char c) {
134             return 123;
135         }
136     }
137 
138     /** The mock. */
139     @Mocked
140     Blah mock;
141 
142     /**
143      * Record same method with disjunctive argument matchers.
144      */
145     @Test
146     void recordSameMethodWithDisjunctiveArgumentMatchers() {
147         new Expectations() {
148             {
149                 mock.doSomething(withEqual(1));
150                 result = false;
151                 mock.doSomething(withNotEqual(1));
152                 result = true;
153             }
154         };
155 
156         assertFalse(mock.doSomething(1));
157         assertTrue(mock.doSomething(2));
158         assertTrue(mock.doSomething(0));
159         assertFalse(mock.doSomething(1));
160     }
161 
162     /**
163      * Record ambiguous expectations using argument matchers.
164      */
165     @Test
166     void recordAmbiguousExpectationsUsingArgumentMatchers() {
167         new Expectations() {
168             {
169                 mock.doSomething(withNotEqual('x'));
170                 result = 1;
171                 mock.doSomething(anyChar);
172                 result = 2;
173             }
174         };
175 
176         assertEquals(1, mock.doSomething('W'));
177         assertEquals(2, mock.doSomething('x'));
178     }
179 
180     /**
181      * Record same method with identical argument matchers.
182      */
183     @Test
184     void recordSameMethodWithIdenticalArgumentMatchers() {
185         new Expectations() {
186             {
187                 mock.doSomething(anyInt);
188                 result = false;
189                 mock.doSomething(anyInt);
190                 result = true; // overrides the previous expectation
191 
192                 mock.doSomething(withNotEqual(5L), withInstanceOf(String.class));
193                 result = 1L;
194                 mock.doSomething(withNotEqual(5L), withInstanceOf(String.class));
195                 result = 2L; // same here
196             }
197         };
198 
199         assertTrue(mock.doSomething(1));
200         assertTrue(mock.doSomething(0));
201 
202         assertEquals(2, mock.doSomething(null, "test 1"));
203         assertEquals(2, mock.doSomething(1L, "test 2"));
204     }
205 
206     /**
207      * Record same method with overlapping argument matchers.
208      */
209     @Test
210     void recordSameMethodWithOverlappingArgumentMatchers() {
211         new Expectations() {
212             {
213                 mock.doSomething(withEqual(0));
214                 result = false;
215                 mock.doSomething(anyInt);
216                 result = true;
217 
218                 mock.doSomething((Long) withNull());
219                 result = 1L;
220                 mock.doSomething((Long) any);
221                 result = 2L;
222             }
223         };
224 
225         assertTrue(mock.doSomething(1));
226         assertFalse(mock.doSomething(0));
227 
228         assertEquals(1, mock.doSomething((Long) null));
229         assertEquals(2, mock.doSomething(1L));
230     }
231 
232     /**
233      * Record same method with exact argument and arg matcher but in wrong order of specificity.
234      */
235     @Test
236     void recordSameMethodWithExactArgumentAndArgMatcherButInWrongOrderOfSpecificity() {
237         new Expectations() {
238             {
239                 mock.doSomething(anyInt);
240                 result = false;
241                 mock.doSomething(1);
242                 result = true; // overrides the previous one (most specific should come first)
243             }
244         };
245 
246         assertTrue(mock.doSomething(1)); // matches last recorded expectation
247         assertFalse(mock.doSomething(2)); // matches no expectation
248     }
249 
250     /**
251      * Record same method with arguments or matchers of varying specificity.
252      */
253     @Test
254     void recordSameMethodWithArgumentsOrMatchersOfVaryingSpecificity() {
255         new Expectations() {
256             {
257                 mock.doSomething(true);
258                 result = null;
259                 mock.doSomething(anyBoolean);
260                 result = "a";
261 
262                 mock.doSomething(1);
263                 result = true;
264                 mock.doSomething(anyInt);
265                 result = false;
266 
267                 mock.doSomething(withEqual('c'));
268                 result = 1;
269                 mock.doSomething(anyChar);
270                 result = 2;
271 
272                 mock.doSomething((String) withNull());
273                 mock.doSomething(withEqual("str"));
274                 result = "b";
275                 mock.doSomething(anyString);
276                 result = "c";
277             }
278         };
279 
280         assertEquals("a", mock.doSomething(false)); // matches only one expectation
281         assertNull(mock.doSomething(true)); // matches two, but most specific was recorded first
282 
283         assertTrue(mock.doSomething(1)); // matches two, but most specific came first
284         assertFalse(mock.doSomething(2)); // matches only one expectation
285 
286         assertEquals(1, mock.doSomething('c')); // matches the first and most specific
287         assertEquals(2, mock.doSomething('3')); // matches only one
288         assertEquals(2, mock.doSomething('x')); // matches only one
289 
290         assertNull(mock.doSomething((String) null)); // matches one specific expectation
291         assertEquals("b", mock.doSomething("str")); // matches another specific expectation
292         assertEquals("c", mock.doSomething("")); // matches the non-specific expectation
293     }
294 
295     /**
296      * Record same method with opposing matchers.
297      */
298     @Test
299     void recordSameMethodWithOpposingMatchers() {
300         new Expectations() {
301             {
302                 mock.doSomething(this.<String> withNull());
303                 result = "null";
304                 mock.doSomething(this.<String> withNotNull());
305                 result = "non-null";
306             }
307         };
308 
309         assertEquals("non-null", mock.doSomething("XYZ"));
310         assertEquals("null", mock.doSomething((String) null));
311     }
312 
313     /**
314      * Record ambiguous expectations using the same matcher but with different arguments.
315      */
316     @Test
317     void recordAmbiguousExpectationsUsingTheSameMatcherButWithDifferentArguments() {
318         new Expectations() {
319             {
320                 mock.doSomething(withNotEqual('A'));
321                 result = 1;
322                 mock.doSomething(withNotEqual('B'));
323                 result = 2; // overrides the previous expectation
324 
325                 mock.doSomething(withAny(1));
326                 result = false;
327                 mock.doSomething(withAny(2));
328                 result = true; // overrides the previous expectation
329             }
330         };
331 
332         assertEquals(2, mock.doSomething('A'));
333         assertEquals(0, mock.doSomething('B'));
334         assertEquals(2, mock.doSomething(' '));
335 
336         assertTrue(mock.doSomething(3));
337         assertTrue(mock.doSomething(1));
338         assertTrue(mock.doSomething(2));
339     }
340 
341     /**
342      * Record unambiguous expectations using the same matcher but with different arguments.
343      */
344     @Test
345     @SuppressWarnings("unused")
346     void recordUnambiguousExpectationsUsingTheSameMatcherButWithDifferentArguments() {
347         new Expectations() {
348             {
349                 mock.doSomething(withEqual("abc"));
350                 result = "first";
351                 mock.doSomething(withEqual("XYZ"));
352                 result = "second";
353 
354                 mock.truncate(withEqual(5.0, 0.1));
355                 result = 1;
356                 mock.truncate(withEqual(-5.0, 0.005));
357                 result = 2;
358 
359                 mock.truncate(withEqual(300.0F, 2));
360                 result = 1;
361                 mock.truncate(withEqual(123.5F, 1));
362                 result = 2;
363 
364                 mock.doSomething(withSameInstance('A'));
365                 result = 1;
366                 mock.doSomething(withSameInstance('B'));
367                 result = 2;
368 
369                 mock.doSomething(1L, withInstanceOf(Long.class));
370                 result = 1L;
371                 mock.doSomething(1L, withInstanceOf(Integer.class));
372                 result = 2L;
373 
374                 mock.doSomething(2L, withInstanceLike(123L));
375                 result = 1L;
376                 mock.doSomething(2L, withInstanceLike(123));
377                 result = 2L;
378 
379                 mock.doSomething(withPrefix("Abc"));
380                 result = "Ap";
381                 mock.doSomething(withPrefix("Xyz"));
382                 result = "Bp";
383 
384                 mock.doSomething(withSuffix("S"));
385                 result = "As";
386                 mock.doSomething(withSuffix("suf"));
387                 result = "Bs";
388 
389                 mock.doSomething(withSubstring("abc"));
390                 result = "sub1";
391                 mock.doSomething(withSubstring("5X"));
392                 result = "sub2";
393 
394                 mock.doSomething(withMatch("[A-F]+"));
395                 result = "letter";
396                 mock.doSomething(withMatch("[0-9]+"));
397                 result = "digit";
398 
399                 mock.doSomething(with(new Delegate<Boolean>() {
400                     boolean matches(boolean b) {
401                         return b;
402                     }
403                 }));
404                 result = "T";
405                 mock.doSomething(with(new Delegate<Boolean>() {
406                     boolean matches(boolean b) {
407                         return !b;
408                     }
409                 }));
410                 result = "F";
411 
412                 mock.doSomething(with(new Delegate<Integer>() {
413                     boolean matches(int i) {
414                         return i > 0;
415                     }
416                 }));
417                 result = true;
418                 mock.doSomething(with(new Delegate<Integer>() {
419                     boolean matches(int i) {
420                         return i < 0;
421                     }
422                 }));
423                 result = false;
424 
425                 mock.doSomething(with(new Delegate<Long>() {
426                     boolean matches(Long l) {
427                         return l == null;
428                     }
429                 }));
430                 result = 1L;
431                 mock.doSomething(with(new Delegate<Long>() {
432                     boolean matches(Long l) {
433                         return l != null;
434                     }
435                 }));
436                 result = 2L;
437             }
438         };
439 
440         assertEquals("second", mock.doSomething("XYZ"));
441         assertEquals("first", mock.doSomething("abc"));
442 
443         assertEquals(2, mock.truncate(-5.001));
444         assertEquals(1, mock.truncate(4.92));
445 
446         assertEquals(2, mock.truncate(123.5F));
447         assertEquals(1, mock.truncate(301.9F));
448 
449         assertEquals(0, mock.doSomething(' '));
450         assertEquals(1, mock.doSomething('A'));
451         assertEquals(2, mock.doSomething('B'));
452 
453         assertEquals(2L, mock.doSomething(1L, 123));
454         assertEquals(1L, mock.doSomething(1L, 123L));
455 
456         assertEquals(2L, mock.doSomething(2L, 123));
457         assertEquals(1L, mock.doSomething(2L, 123L));
458 
459         assertEquals("Bp", mock.doSomething("XyzAbc"));
460         assertEquals("Ap", mock.doSomething("AbcXyz"));
461 
462         assertEquals("Bs", mock.doSomething("asDfsuf"));
463         assertEquals("As", mock.doSomething("sfj43S"));
464 
465         assertEquals("sub2", mock.doSomething(" 5X  234 TY"));
466         assertEquals("sub1", mock.doSomething("AsdabcJ343"));
467 
468         assertEquals("digit", mock.doSomething("34502"));
469         assertEquals("letter", mock.doSomething("AEFCB"));
470 
471         assertEquals("T", mock.doSomething(true));
472         assertEquals("F", mock.doSomething(false));
473 
474         assertTrue(mock.doSomething(34));
475         assertFalse(mock.doSomething(0));
476         assertFalse(mock.doSomething(-12));
477 
478         assertEquals(1L, mock.doSomething((Long) null));
479         assertEquals(2L, mock.doSomething(123L));
480     }
481 
482     /**
483      * Record unambiguous expectations with same matcher for one parameter and different arguments for another.
484      */
485     @Test
486     void recordUnambiguousExpectationsWithSameMatcherForOneParameterAndDifferentArgumentsForAnother() {
487         Blah b = new Blah();
488 
489         new Expectations() {
490             {
491                 mock.doSomething(anyLong, "A");
492                 result = 1L;
493                 mock.doSomething(anyLong, "B");
494                 result = 2L;
495             }
496         };
497 
498         assertEquals(1L, b.doSomething(1L, "A"));
499         assertEquals(2L, b.doSomething(2L, "B"));
500         assertEquals(0L, b.doSomething(1L, "c"));
501         assertEquals(1L, b.doSomething(1L, "A"));
502         assertEquals(2L, b.doSomething(0L, "B"));
503         assertEquals(0L, b.doSomething(0L, null));
504     }
505 
506     /**
507      * Record overlapping expectations with same matcher for one parameter and different arguments for another.
508      */
509     @Test
510     void recordOverlappingExpectationsWithSameMatcherForOneParameterAndDifferentArgumentsForAnother() {
511         Blah b = new Blah();
512 
513         new Expectations() {
514             {
515                 mock.doSomething(anyLong, "A");
516                 result = 1L;
517                 mock.doSomething(anyLong, null);
518                 result = 2L;
519             }
520         };
521 
522         assertEquals(1L, b.doSomething(1L, "A"));
523         assertEquals(2L, b.doSomething(2L, "B"));
524         assertEquals(2L, b.doSomething(1L, "c"));
525         assertEquals(1L, b.doSomething(2L, "A"));
526         assertEquals(2L, b.doSomething(0L, "B"));
527         assertEquals(2L, b.doSomething(0L, null));
528     }
529 
530     /**
531      * Record multiple non strict expectations with same delegate.
532      */
533     @Test
534     void recordMultipleNonStrictExpectationsWithSameDelegate() {
535         final Delegate<String> delegate = new Delegate<String>() {
536             @SuppressWarnings("unused")
537             boolean matches(String arg) {
538                 return !arg.isEmpty();
539             }
540         };
541 
542         new Expectations() {
543             {
544                 mock.doSomething(with(delegate));
545                 result = "first";
546             }
547         };
548 
549         assertEquals("first", mock.doSomething("test1"));
550 
551         new Expectations() {
552             {
553                 mock.doSomething(with(delegate));
554                 result = "second";
555             }
556         };
557 
558         assertEquals("second", mock.doSomething("test2"));
559     }
560 }