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.fail;
9   
10  import java.util.Date;
11  
12  import mockit.integration.junit5.ExpectedException;
13  import mockit.integration.junit5.JMockitExtension;
14  import mockit.internal.expectations.invocation.MissingInvocation;
15  import mockit.internal.expectations.invocation.UnexpectedInvocation;
16  
17  import org.junit.jupiter.api.Assertions;
18  import org.junit.jupiter.api.Test;
19  import org.junit.jupiter.api.extension.ExtendWith;
20  
21  /**
22   * The Class ExpectationsWithInvocationCountsTest.
23   */
24  @ExtendWith(JMockitExtension.class)
25  class ExpectationsWithInvocationCountsTest {
26  
27      /** The code under test. */
28      private final CodeUnderTest codeUnderTest = new CodeUnderTest();
29  
30      /**
31       * The Class CodeUnderTest.
32       */
33      static class CodeUnderTest {
34  
35          /** The dependency. */
36          private final Collaborator dependency = new Collaborator();
37  
38          /**
39           * Do something.
40           */
41          void doSomething() {
42              dependency.provideSomeService();
43          }
44  
45          /**
46           * Do something else.
47           */
48          void doSomethingElse() {
49              dependency.simpleOperation(1, "b", null);
50          }
51      }
52  
53      /**
54       * The Class Collaborator.
55       */
56      static class Collaborator {
57  
58          /**
59           * Instantiates a new collaborator.
60           */
61          Collaborator() {
62          }
63  
64          /**
65           * Instantiates a new collaborator.
66           *
67           * @param value
68           *            the value
69           */
70          Collaborator(@SuppressWarnings("unused") int value) {
71          }
72  
73          /**
74           * Provide some service.
75           */
76          void provideSomeService() {
77          }
78  
79          /**
80           * Simple operation.
81           *
82           * @param a
83           *            the a
84           * @param b
85           *            the b
86           * @param c
87           *            the c
88           */
89          @SuppressWarnings("UnusedDeclaration")
90          final void simpleOperation(int a, String b, Date c) {
91          }
92      }
93  
94      /**
95       * Expect once.
96       *
97       * @param mock
98       *            the mock
99       */
100     @Test
101     void expectOnce(@Mocked final Collaborator mock) {
102         new Expectations() {
103             {
104                 mock.provideSomeService();
105             }
106         };
107 
108         codeUnderTest.doSomething();
109     }
110 
111     /**
112      * Expect once but replay twice.
113      *
114      * @param mock
115      *            the mock
116      */
117     @Test
118     @ExpectedException(UnexpectedInvocation.class)
119     void expectOnceButReplayTwice(@Mocked final Collaborator mock) {
120         new Expectations() {
121             {
122                 mock.provideSomeService();
123                 times = 1;
124             }
125         };
126 
127         codeUnderTest.doSomething();
128         codeUnderTest.doSomething();
129 
130         fail("Should not get here");
131     }
132 
133     /**
134      * Expect once but replay more times.
135      *
136      * @param mock
137      *            the mock
138      */
139     @Test
140     @ExpectedException(UnexpectedInvocation.class)
141     void expectOnceButReplayMoreTimes(@Mocked final Collaborator mock) {
142         new Expectations() {
143             {
144                 mock.provideSomeService();
145                 times = 1;
146             }
147         };
148 
149         codeUnderTest.doSomething();
150 
151         try {
152             codeUnderTest.doSomething();
153         } finally {
154             codeUnderTest.doSomethingElse();
155         }
156 
157         fail("Should not get here");
158     }
159 
160     /**
161      * Catch unexpected invocation and continue.
162      *
163      * @param mock
164      *            the mock
165      */
166     @Test
167     void catchUnexpectedInvocationAndContinue(@Mocked final Collaborator mock) {
168         new Expectations() {
169             {
170                 mock.provideSomeService();
171                 maxTimes = 0;
172             }
173         };
174 
175         try {
176             mock.provideSomeService();
177         } catch (UnexpectedInvocation ignore) {
178         }
179 
180         mock.simpleOperation(1, "", null);
181     }
182 
183     /**
184      * Expect twice by using invocation count.
185      *
186      * @param mock
187      *            the mock
188      */
189     @Test
190     void expectTwiceByUsingInvocationCount(@Mocked final Collaborator mock) {
191         new Expectations() {
192             {
193                 mock.provideSomeService();
194                 times = 2;
195                 mock.simpleOperation(1, "b", null);
196             }
197         };
198 
199         codeUnderTest.doSomething();
200         codeUnderTest.doSomething();
201         codeUnderTest.doSomethingElse();
202     }
203 
204     /**
205      * Expect twice by using invocation count but replay only once.
206      *
207      * @param mock
208      *            the mock
209      */
210     @Test
211     @ExpectedException(MissingInvocation.class)
212     void expectTwiceByUsingInvocationCountButReplayOnlyOnce(@Mocked final Collaborator mock) {
213         new Expectations() {
214             {
215                 mock.provideSomeService();
216                 times = 2;
217                 mock.simpleOperation(1, "b", null);
218             }
219         };
220 
221         codeUnderTest.doSomething();
222         codeUnderTest.doSomethingElse();
223     }
224 
225     /**
226      * Expect exactly twice but replay more times.
227      *
228      * @param mock
229      *            the mock
230      */
231     @Test
232     @ExpectedException(UnexpectedInvocation.class)
233     void expectExactlyTwiceButReplayMoreTimes(@Mocked final Collaborator mock) {
234         new Expectations() {
235             {
236                 mock.provideSomeService();
237                 times = 2;
238             }
239         };
240 
241         codeUnderTest.doSomething();
242         codeUnderTest.doSomething();
243         codeUnderTest.doSomething();
244     }
245 
246     /**
247      * Expect at least once and replay twice.
248      *
249      * @param mock
250      *            the mock
251      */
252     @Test
253     void expectAtLeastOnceAndReplayTwice(@Mocked final Collaborator mock) {
254         new Expectations() {
255             {
256                 mock.provideSomeService();
257                 minTimes = 1;
258                 mock.simpleOperation(1, "b", null);
259             }
260         };
261 
262         codeUnderTest.doSomething();
263         codeUnderTest.doSomething();
264         codeUnderTest.doSomethingElse();
265     }
266 
267     /**
268      * Expect at least twice but replay once with single expectation.
269      *
270      * @param mock
271      *            the mock
272      */
273     @Test
274     @ExpectedException(MissingInvocation.class)
275     void expectAtLeastTwiceButReplayOnceWithSingleExpectation(@Mocked final Collaborator mock) {
276         new Expectations() {
277             {
278                 mock.provideSomeService();
279                 minTimes = 2;
280             }
281         };
282 
283         codeUnderTest.doSomething();
284     }
285 
286     /**
287      * Expect at least twice but replay once with two consecutive expectations.
288      *
289      * @param mock
290      *            the mock
291      */
292     @Test
293     @ExpectedException(MissingInvocation.class)
294     void expectAtLeastTwiceButReplayOnceWithTwoConsecutiveExpectations(@Mocked final Collaborator mock) {
295         new Expectations() {
296             {
297                 mock.provideSomeService();
298                 minTimes = 2;
299                 mock.simpleOperation(1, "b", null);
300             }
301         };
302 
303         codeUnderTest.doSomething();
304         codeUnderTest.doSomethingElse();
305     }
306 
307     /**
308      * Repeats at least overwriting upper limit.
309      *
310      * @param mock
311      *            the mock
312      */
313     @Test
314     void repeatsAtLeastOverwritingUpperLimit(@Mocked final Collaborator mock) {
315         new Expectations() {
316             {
317                 mock.provideSomeService();
318                 maxTimes = 2;
319                 minTimes = 1;
320             }
321         };
322 
323         codeUnderTest.doSomething();
324         codeUnderTest.doSomething();
325         codeUnderTest.doSomething();
326     }
327 
328     /**
329      * Expect at most twice and replay once.
330      *
331      * @param mock
332      *            the mock
333      */
334     @Test
335     void expectAtMostTwiceAndReplayOnce(@Mocked final Collaborator mock) {
336         new Expectations() {
337             {
338                 mock.provideSomeService();
339                 maxTimes = 2;
340                 mock.simpleOperation(1, "b", null);
341             }
342         };
343 
344         codeUnderTest.doSomething();
345         codeUnderTest.doSomethingElse();
346     }
347 
348     /**
349      * Expect at most once but replay twice.
350      *
351      * @param mock
352      *            the mock
353      */
354     @Test
355     @ExpectedException(MissingInvocation.class)
356     void expectAtMostOnceButReplayTwice(@Mocked final Collaborator mock) {
357         Assertions.assertThrows(UnexpectedInvocation.class, () -> {
358             new Expectations() {
359                 {
360                     mock.provideSomeService();
361                     maxTimes = 1;
362                     mock.simpleOperation(1, "b", null);
363                 }
364             };
365 
366             codeUnderTest.doSomething();
367             codeUnderTest.doSomething();
368             codeUnderTest.doSomethingElse();
369         });
370     }
371 
372     /**
373      * Repeats at most does not overwrite lower limit.
374      *
375      * @param mock
376      *            the mock
377      */
378     @Test
379     @ExpectedException(MissingInvocation.class)
380     void repeatsAtMostDoesNotOverwriteLowerLimit(@Mocked final Collaborator mock) {
381         new Expectations() {
382             {
383                 mock.provideSomeService();
384                 minTimes = 2;
385                 maxTimes = 3;
386             }
387         };
388 
389         codeUnderTest.doSomething();
390     }
391 
392     /**
393      * Expect same method once or twice then once but replay each expectation only once.
394      *
395      * @param mock
396      *            the mock
397      */
398     @Test
399     void expectSameMethodOnceOrTwiceThenOnceButReplayEachExpectationOnlyOnce(@Mocked final Collaborator mock) {
400         new Expectations() {
401             {
402                 mock.simpleOperation(1, "", null);
403                 minTimes = 1;
404                 maxTimes = 2;
405                 mock.simpleOperation(2, "", null);
406             }
407         };
408 
409         mock.simpleOperation(1, "", null);
410         mock.simpleOperation(2, "", null);
411     }
412 
413     /**
414      * Expect two or three times.
415      *
416      * @param mock
417      *            the mock
418      */
419     @Test
420     void expectTwoOrThreeTimes(@Mocked final Collaborator mock) {
421         new Expectations() {
422             {
423                 mock.provideSomeService();
424                 minTimes = 2;
425                 maxTimes = 3;
426                 mock.simpleOperation(1, "b", null);
427             }
428         };
429 
430         codeUnderTest.doSomething();
431         codeUnderTest.doSomething();
432         codeUnderTest.doSomethingElse();
433     }
434 
435     /**
436      * Expect zero or more times and replay twice.
437      *
438      * @param mock
439      *            the mock
440      */
441     @Test
442     void expectZeroOrMoreTimesAndReplayTwice(@Mocked final Collaborator mock) {
443         new Expectations() {
444             {
445                 mock.provideSomeService();
446                 minTimes = 0;
447                 maxTimes = -1;
448                 mock.simpleOperation(1, "b", null);
449             }
450         };
451 
452         codeUnderTest.doSomething();
453         codeUnderTest.doSomething();
454         codeUnderTest.doSomethingElse();
455     }
456 
457     /**
458      * Expect at least one invocation matching strict expectation but invoke none.
459      *
460      * @param a
461      *            the a
462      */
463     @Test
464     @ExpectedException(MissingInvocation.class)
465     void expectAtLeastOneInvocationMatchingStrictExpectationButInvokeNone(@Mocked final Collaborator a) {
466         new Expectations() {
467             {
468                 a.provideSomeService();
469                 maxTimes = -1;
470             }
471         };
472 
473         // Do nothing at replay time.
474     }
475 
476     /**
477      * Expect one or more invocations followed by another which wont occur max times.
478      *
479      * @param mock
480      *            the mock
481      */
482     @Test
483     @ExpectedException(MissingInvocation.class)
484     void expectOneOrMoreInvocationsFollowedByAnotherWhichWontOccur_maxTimes(@Mocked final Collaborator mock) {
485         new Expectations() {
486             {
487                 mock.provideSomeService();
488                 maxTimes = -1;
489                 mock.simpleOperation(1, null, null);
490             }
491         };
492 
493         codeUnderTest.doSomething();
494     }
495 
496     /**
497      * Expect one or more invocations followed by another which wont occur min times.
498      *
499      * @param mock
500      *            the mock
501      */
502     @Test
503     @ExpectedException(MissingInvocation.class)
504     void expectOneOrMoreInvocationsFollowedByAnotherWhichWontOccur_minTimes(@Mocked final Collaborator mock) {
505         new Expectations() {
506             {
507                 mock.simpleOperation(1, anyString, null);
508                 minTimes = 1;
509                 mock.provideSomeService();
510             }
511         };
512 
513         codeUnderTest.doSomethingElse();
514     }
515 }