View Javadoc
1   package mockit;
2   
3   import static org.junit.jupiter.api.Assertions.assertEquals;
4   import static org.junit.jupiter.api.Assertions.assertFalse;
5   import static org.junit.jupiter.api.Assertions.assertSame;
6   import static org.junit.jupiter.api.Assertions.assertThrows;
7   import static org.junit.jupiter.api.Assertions.assertTrue;
8   
9   import mockit.internal.expectations.invocation.MissingInvocation;
10  
11  import org.junit.jupiter.api.Test;
12  
13  /**
14   * The Class DynamicOnInstanceMockingTest.
15   */
16  final class DynamicOnInstanceMockingTest {
17  
18      /**
19       * The Class Collaborator.
20       */
21      static class Collaborator {
22  
23          /** The value. */
24          protected int value;
25  
26          /**
27           * Instantiates a new collaborator.
28           */
29          Collaborator() {
30              value = -1;
31          }
32  
33          /**
34           * Instantiates a new collaborator.
35           *
36           * @param value
37           *            the value
38           */
39          Collaborator(int value) {
40              this.value = value;
41          }
42  
43          /**
44           * Gets the value.
45           *
46           * @return the value
47           */
48          int getValue() {
49              return value;
50          }
51  
52          /**
53           * Sets the value.
54           *
55           * @param value
56           *            the new value
57           */
58          void setValue(int value) {
59              this.value = value;
60          }
61      }
62  
63      /**
64       * The Class AnotherDependency.
65       */
66      static class AnotherDependency {
67  
68          /**
69           * Gets the name.
70           *
71           * @return the name
72           */
73          public String getName() {
74              return "";
75          }
76      }
77  
78      /**
79       * Mocking one instance and matching invocations only on that instance.
80       */
81      @Test
82      void mockingOneInstanceAndMatchingInvocationsOnlyOnThatInstance() {
83          Collaborator collaborator1 = new Collaborator();
84          Collaborator collaborator2 = new Collaborator();
85          final Collaborator collaborator3 = new Collaborator();
86  
87          new Expectations(collaborator3) {
88              {
89                  collaborator3.getValue();
90                  result = 3;
91              }
92          };
93  
94          assertEquals(-1, collaborator1.getValue());
95          assertEquals(-1, collaborator2.getValue());
96          assertEquals(3, collaborator3.getValue());
97          assertEquals(2, new Collaborator(2).getValue());
98      }
99  
100     /**
101      * Mocking two instances and matching invocations on each one.
102      */
103     @Test
104     void mockingTwoInstancesAndMatchingInvocationsOnEachOne() {
105         final Collaborator collaborator1 = new Collaborator();
106         Collaborator collaborator2 = new Collaborator();
107 
108         new Expectations(collaborator1, collaborator2) {
109             {
110                 collaborator1.getValue();
111                 result = 1;
112             }
113         };
114 
115         collaborator2.setValue(2);
116         assertEquals(2, collaborator2.getValue());
117         assertEquals(1, collaborator1.getValue());
118         assertEquals(3, new Collaborator(3).getValue());
119     }
120 
121     /**
122      * Mocking one instance but recording on another.
123      */
124     @Test
125     void mockingOneInstanceButRecordingOnAnother() {
126         Collaborator collaborator1 = new Collaborator();
127         final Collaborator collaborator2 = new Collaborator();
128         Collaborator collaborator3 = new Collaborator();
129 
130         new Expectations(collaborator1) {
131             {
132                 // A misuse of the API:
133                 collaborator2.getValue();
134                 result = -2;
135             }
136         };
137 
138         collaborator1.setValue(1);
139         collaborator2.setValue(2);
140         collaborator3.setValue(3);
141         assertEquals(1, collaborator1.getValue());
142         assertEquals(-2, collaborator2.getValue());
143         assertEquals(3, collaborator3.getValue());
144     }
145 
146     /**
147      * The Class Foo.
148      */
149     public static class Foo {
150 
151         /**
152          * Builds the value.
153          *
154          * @param s
155          *            the s
156          *
157          * @return the foo
158          */
159         Foo buildValue(@SuppressWarnings("unused") String s) {
160             return this;
161         }
162 
163         /**
164          * Do it.
165          *
166          * @return true, if successful
167          */
168         boolean doIt() {
169             return false;
170         }
171 
172         /**
173          * Do it again.
174          *
175          * @return true, if successful
176          */
177         boolean doItAgain() {
178             return false;
179         }
180 
181         /**
182          * Gets the bar.
183          *
184          * @return the bar
185          */
186         AnotherDependency getBar() {
187             return null;
188         }
189     }
190 
191     /**
192      * The Class SubFoo.
193      */
194     public static class SubFoo extends Foo {
195     }
196 
197     /**
198      * Record duplicate invocation on two dynamic mocks of different types but shared base class.
199      */
200     @Test
201     void recordDuplicateInvocationOnTwoDynamicMocksOfDifferentTypesButSharedBaseClass() {
202         final Foo f1 = new Foo();
203         final SubFoo f2 = new SubFoo();
204 
205         new Expectations(f1, f2) {
206             {
207                 f1.doIt();
208                 result = true;
209                 f2.doIt();
210                 result = false;
211             }
212         };
213 
214         assertTrue(f1.doIt());
215         assertFalse(f2.doIt());
216         assertFalse(new Foo().doIt());
217         assertFalse(new SubFoo().doIt());
218     }
219 
220     /**
221      * Verify method invocation count on mocked and non mocked instances.
222      */
223     @Test
224     void verifyMethodInvocationCountOnMockedAndNonMockedInstances() {
225         final Foo foo1 = new Foo();
226         final Foo foo2 = new Foo();
227 
228         new Expectations(foo1, foo2) {
229             {
230                 foo1.doIt();
231                 result = true;
232             }
233         };
234 
235         assertTrue(foo1.doIt());
236         assertFalse(foo2.doItAgain());
237         assertFalse(foo2.doIt());
238         final Foo foo3 = new Foo();
239         assertFalse(foo1.doItAgain());
240         assertFalse(foo3.doItAgain());
241         assertFalse(foo3.doIt());
242         assertFalse(foo3.doItAgain());
243 
244         new Verifications() {
245             {
246                 assertFalse(foo2.doIt());
247                 times = 1;
248                 assertFalse(foo1.doItAgain());
249                 times = 1;
250                 assertFalse(foo3.doItAgain());
251                 times = 2;
252             }
253         };
254     }
255 
256     /**
257      * Creates the cascaded mock from partially mocked instance.
258      */
259     @Test
260     void createCascadedMockFromPartiallyMockedInstance() {
261         final Foo foo = new Foo();
262 
263         new Expectations(foo) {
264             {
265                 foo.getBar().getName();
266                 result = "cascade";
267             }
268         };
269 
270         assertEquals("cascade", foo.getBar().getName());
271     }
272 
273     /**
274      * Use available mocked instance as cascade from partially mocked instance.
275      *
276      * @param bar
277      *            the bar
278      */
279     @Test
280     void useAvailableMockedInstanceAsCascadeFromPartiallyMockedInstance(@Mocked AnotherDependency bar) {
281         final Foo foo = new Foo();
282 
283         new Expectations(foo) {
284             {
285                 foo.getBar().getName();
286                 result = "cascade";
287             }
288         };
289 
290         AnotherDependency cascadedBar = foo.getBar();
291         assertSame(bar, cascadedBar);
292         assertEquals("cascade", cascadedBar.getName());
293     }
294 
295     /**
296      * The Class Bar.
297      */
298     static final class Bar extends AnotherDependency {
299     }
300 
301     /**
302      * Use available mocked subclass instance as cascade from partially mocked instance.
303      *
304      * @param bar
305      *            the bar
306      */
307     @Test
308     void useAvailableMockedSubclassInstanceAsCascadeFromPartiallyMockedInstance(@Mocked Bar bar) {
309         final Foo foo = new Foo();
310 
311         new Expectations(foo) {
312             {
313                 foo.getBar().getName();
314                 result = "cascade";
315             }
316         };
317 
318         AnotherDependency cascadedBar = foo.getBar();
319         assertSame(bar, cascadedBar);
320         assertEquals("cascade", cascadedBar.getName());
321     }
322 
323     /**
324      * Use itself as cascade from partially mocked instance.
325      */
326     @Test
327     void useItselfAsCascadeFromPartiallyMockedInstance() {
328         final Foo foo = new Foo();
329 
330         new Expectations(foo) {
331             {
332                 foo.buildValue(anyString).doIt();
333                 result = true;
334             }
335         };
336 
337         Foo cascadedFoo = foo.buildValue("test");
338         assertSame(foo, cascadedFoo);
339         assertTrue(cascadedFoo.doIt());
340     }
341 
342     /**
343      * Verify single invocation to mocked instance with additional invocation to same method on another instance.
344      */
345     @Test
346     void verifySingleInvocationToMockedInstanceWithAdditionalInvocationToSameMethodOnAnotherInstance() {
347         final Collaborator mocked = new Collaborator();
348 
349         new Expectations(mocked) {
350         };
351 
352         Collaborator notMocked = new Collaborator();
353         assertEquals(-1, notMocked.getValue());
354         assertEquals(-1, mocked.getValue());
355 
356         new Verifications() {
357             {
358                 mocked.getValue();
359                 times = 1;
360             }
361         };
362     }
363 
364     /**
365      * Verify ordered invocations to dynamically mocked instance with another instance involved but missing an
366      * invocation.
367      */
368     @Test
369     void verifyOrderedInvocationsToDynamicallyMockedInstanceWithAnotherInstanceInvolvedButMissingAnInvocation() {
370         assertThrows(MissingInvocation.class, () -> {
371             final Collaborator mock = new Collaborator();
372 
373             new Expectations(mock) {
374             };
375 
376             mock.setValue(1);
377             new Collaborator().setValue(2);
378 
379             new VerificationsInOrder() {
380                 {
381                     mock.setValue(1);
382                     times = 1;
383                     mock.setValue(2);
384                     times = 1; // must be missing
385                 }
386             };
387         });
388     }
389 
390     /**
391      * Verify ordered invocations to dynamically mocked instance with another instance involved.
392      */
393     @Test
394     void verifyOrderedInvocationsToDynamicallyMockedInstanceWithAnotherInstanceInvolved() {
395         final Collaborator mock = new Collaborator();
396 
397         new Expectations(mock) {
398             {
399                 mock.setValue(anyInt);
400             }
401         };
402 
403         mock.setValue(1);
404         new Collaborator().setValue(2);
405 
406         new VerificationsInOrder() {
407             {
408                 mock.setValue(1);
409                 times = 1;
410                 mock.setValue(2);
411                 times = 0;
412             }
413         };
414     }
415 }