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.assertTrue;
10  
11  import edu.umd.cs.findbugs.annotations.NonNull;
12  
13  import java.io.StringReader;
14  import java.nio.CharBuffer;
15  
16  import org.junit.jupiter.api.AfterAll;
17  import org.junit.jupiter.api.AfterEach;
18  import org.junit.jupiter.api.BeforeAll;
19  import org.junit.jupiter.api.BeforeEach;
20  import org.junit.jupiter.api.MethodOrderer.MethodName;
21  import org.junit.jupiter.api.Test;
22  import org.junit.jupiter.api.TestMethodOrder;
23  
24  /**
25   * The Class FakingBaseTypesTest.
26   */
27  @TestMethodOrder(MethodName.class)
28  final class FakingBaseTypesTest {
29  
30      /**
31       * The Class BeforeClassBaseAction.
32       */
33      static class BeforeClassBaseAction {
34          /**
35           * Perform.
36           *
37           * @return the int
38           */
39          protected int perform() {
40              return -1;
41          }
42      }
43  
44      /**
45       * The Class BeforeClassAction.
46       */
47      static class BeforeClassAction extends BeforeClassBaseAction {
48          @Override
49          protected int perform() {
50              return 12;
51          }
52      }
53  
54      /**
55       * Apply fake for all tests.
56       *
57       * @param <T>
58       *            the generic type
59       */
60      @BeforeAll
61      static <T extends BeforeClassBaseAction> void applyFakeForAllTests() {
62          new MockUp<T>() {
63              @Mock
64              int perform() {
65                  return 34;
66              }
67          };
68      }
69  
70      /**
71       * Verify fake for all tests is in effect.
72       */
73      @AfterAll
74      static void verifyFakeForAllTestsIsInEffect() {
75          int i1 = new BeforeClassAction().perform();
76          int i2 = new BeforeClassBaseAction().perform();
77  
78          assertEquals(34, i1);
79          assertEquals(34, i2);
80      }
81  
82      /**
83       * The Interface IBeforeAction.
84       */
85      public interface IBeforeAction {
86          /**
87           * Perform.
88           *
89           * @return the int
90           */
91          @SuppressWarnings("unused")
92          int perform();
93      }
94  
95      /**
96       * The Class BeforeAction.
97       */
98      static class BeforeAction implements IBeforeAction {
99          @Override
100         public int perform() {
101             return 123;
102         }
103     }
104 
105     /**
106      * Apply fake for each test.
107      *
108      * @param <T>
109      *            the generic type
110      */
111     @BeforeEach
112     <T extends IBeforeAction> void applyFakeForEachTest() {
113         new MockUp<T>() {
114             @Mock
115             int perform() {
116                 return 56;
117             }
118         };
119     }
120 
121     /**
122      * Verify fake for each test is in effect.
123      */
124     @AfterEach
125     void verifyFakeForEachTestIsInEffect() {
126         int i = new BeforeAction().perform();
127         assertEquals(56, i);
128     }
129 
130     /**
131      * The Interface IAction.
132      */
133     public interface IAction {
134 
135         /**
136          * Perform.
137          *
138          * @param i
139          *            the i
140          *
141          * @return the int
142          */
143         int perform(int i);
144 
145         /**
146          * Not to be faked.
147          *
148          * @return true, if successful
149          */
150         boolean notToBeFaked();
151     }
152 
153     /**
154      * The Class ActionImpl1.
155      */
156     public static class ActionImpl1 implements IAction {
157         @Override
158         public int perform(int i) {
159             return i - 1;
160         }
161 
162         @Override
163         public boolean notToBeFaked() {
164             return true;
165         }
166     }
167 
168     /**
169      * The Class ActionImpl2.
170      */
171     static final class ActionImpl2 implements IAction {
172         @Override
173         public int perform(int i) {
174             return i - 2;
175         }
176 
177         @Override
178         public boolean notToBeFaked() {
179             return true;
180         }
181     }
182 
183     /** The action I. */
184     IAction actionI;
185 
186     /**
187      * Test 3 fake interface implementation classes using anonymous fake.
188      *
189      * @param <T>
190      *            the generic type
191      */
192     @Test
193     <T extends IAction> void test3_fakeInterfaceImplementationClassesUsingAnonymousFake() {
194         actionI = new ActionImpl1();
195 
196         new MockUp<T>() {
197             @Mock
198             int perform(int i) {
199                 return i + 1;
200             }
201         };
202 
203         assertEquals(2, actionI.perform(1));
204         assertTrue(actionI.notToBeFaked());
205 
206         ActionImpl2 impl2 = new ActionImpl2();
207         assertEquals(3, impl2.perform(2));
208         assertTrue(impl2.notToBeFaked());
209     }
210 
211     /**
212      * The Interface TestInterface.
213      */
214     public interface TestInterface {
215         /**
216          * Gets the data.
217          *
218          * @return the data
219          */
220         String getData();
221     }
222 
223     /**
224      * The Class FakeTestInterface.
225      *
226      * @param <T>
227      *            the generic type
228      */
229     public static final class FakeTestInterface<T extends TestInterface> extends MockUp<T> {
230 
231         /**
232          * Gets the data.
233          *
234          * @param inv
235          *            the inv
236          *
237          * @return the data
238          */
239         @Mock
240         public String getData(Invocation inv) {
241             return "faked" + inv.proceed();
242         }
243     }
244 
245     /**
246      * Fake all classes implementing an interface using named fake with invocation parameter.
247      */
248     @Test
249     void fakeAllClassesImplementingAnInterfaceUsingNamedFakeWithInvocationParameter() {
250         TestInterface impl1 = new TestInterface() {
251             @Override
252             public String getData() {
253                 return "1";
254             }
255         };
256         TestInterface impl2 = new TestInterface() {
257             @Override
258             public String getData() {
259                 return "2";
260             }
261         };
262         new FakeTestInterface();
263 
264         String faked1 = impl1.getData();
265         String faked2 = impl2.getData();
266 
267         assertEquals("faked1", faked1);
268         assertEquals("faked2", faked2);
269     }
270 
271     /**
272      * The Class BaseAction.
273      */
274     public abstract static class BaseAction {
275 
276         /**
277          * Perform.
278          *
279          * @param i
280          *            the i
281          *
282          * @return the int
283          */
284         protected abstract int perform(int i);
285 
286         /**
287          * To be faked as well.
288          *
289          * @return the int
290          */
291         public int toBeFakedAsWell() {
292             return -1;
293         }
294 
295         /**
296          * Not to be faked.
297          *
298          * @return the int
299          */
300         int notToBeFaked() {
301             return 1;
302         }
303     }
304 
305     /**
306      * The Class ConcreteAction1.
307      */
308     static final class ConcreteAction1 extends BaseAction {
309         @Override
310         public int perform(int i) {
311             return i - 1;
312         }
313     }
314 
315     /**
316      * The Class ConcreteAction2.
317      */
318     static class ConcreteAction2 extends BaseAction {
319         @Override
320         protected int perform(int i) {
321             return i - 2;
322         }
323 
324         @Override
325         public int toBeFakedAsWell() {
326             return super.toBeFakedAsWell() - 1;
327         }
328 
329         @Override
330         int notToBeFaked() {
331             return super.notToBeFaked() + 1;
332         }
333     }
334 
335     /**
336      * The Class ConcreteAction3.
337      */
338     static class ConcreteAction3 extends ConcreteAction2 {
339         @Override
340         public int perform(int i) {
341             return i - 3;
342         }
343 
344         @Override
345         public int toBeFakedAsWell() {
346             return -3;
347         }
348 
349         @Override
350         final int notToBeFaked() {
351             return 3;
352         }
353     }
354 
355     /** The action B. */
356     BaseAction actionB;
357 
358     /**
359      * Test 4 fake concrete subclasses using anonymous fake.
360      *
361      * @param <T>
362      *            the generic type
363      */
364     @Test
365     <T extends BaseAction> void test4_fakeConcreteSubclassesUsingAnonymousFake() {
366         actionB = new ConcreteAction1();
367 
368         new MockUp<T>() {
369             @Mock
370             int perform(int i) {
371                 return i + 1;
372             }
373 
374             @Mock
375             int toBeFakedAsWell() {
376                 return 123;
377             }
378         };
379 
380         assertEquals(2, actionB.perform(1));
381         assertEquals(123, actionB.toBeFakedAsWell());
382         assertEquals(1, actionB.notToBeFaked());
383 
384         ConcreteAction2 action2 = new ConcreteAction2();
385         assertEquals(3, action2.perform(2));
386         assertEquals(123, action2.toBeFakedAsWell());
387         assertEquals(2, action2.notToBeFaked());
388 
389         ConcreteAction3 action3 = new ConcreteAction3();
390         assertEquals(4, action3.perform(3));
391         assertEquals(123, action3.toBeFakedAsWell());
392         assertEquals(3, action3.notToBeFaked());
393     }
394 
395     /**
396      * Check implementation classes are no longer faked.
397      */
398     @AfterEach
399     void checkImplementationClassesAreNoLongerFaked() {
400         if (actionI != null) {
401             assertEquals(-1, actionI.perform(0));
402         }
403 
404         assertEquals(-2, new ActionImpl2().perform(0));
405 
406         if (actionB != null) {
407             assertEquals(-1, actionB.perform(0));
408         }
409 
410         assertEquals(-2, new ConcreteAction2().perform(0));
411         assertEquals(-3, new ConcreteAction3().perform(0));
412     }
413 
414     /**
415      * The Class FakeInterface.
416      *
417      * @param <T>
418      *            the generic type
419      */
420     static final class FakeInterface<T extends IAction> extends MockUp<T> {
421 
422         /**
423          * Perform.
424          *
425          * @param i
426          *            the i
427          *
428          * @return the int
429          */
430         @Mock
431         int perform(int i) {
432             return i + 2;
433         }
434     }
435 
436     /**
437      * Test 5 fake interface implementation classes using named fake.
438      */
439     @Test
440     void test5_fakeInterfaceImplementationClassesUsingNamedFake() {
441         new FakeInterface();
442 
443         actionI = new ActionImpl1();
444         assertEquals(3, actionI.perform(1));
445         assertEquals(4, new ActionImpl2().perform(2));
446     }
447 
448     /**
449      * The Class FakeBaseClass.
450      *
451      * @param <T>
452      *            the generic type
453      */
454     static final class FakeBaseClass<T extends BaseAction> extends MockUp<T> {
455 
456         /**
457          * Perform.
458          *
459          * @param i
460          *            the i
461          *
462          * @return the int
463          */
464         @Mock
465         int perform(int i) {
466             return i + 3;
467         }
468     }
469 
470     /**
471      * Test 6 fake concrete subclasses using named fake.
472      */
473     @Test
474     void test6_fakeConcreteSubclassesUsingNamedFake() {
475         new FakeBaseClass();
476 
477         actionB = new ConcreteAction1();
478         assertEquals(4, actionB.perform(1));
479         assertEquals(5, new ConcreteAction2().perform(2));
480         assertEquals(6, new ConcreteAction3().perform(3));
481     }
482 
483     /**
484      * The Interface GenericIAction.
485      *
486      * @param <N>
487      *            the number type
488      */
489     interface GenericIAction<N extends Number> {
490         /**
491          * Perform.
492          *
493          * @param n
494          *            the n
495          *
496          * @return the n
497          */
498         N perform(N n);
499     }
500 
501     /**
502      * Test 7 fake implementations of generic interface.
503      *
504      * @param <M>
505      *            the generic type
506      */
507     @Test
508     <M extends GenericIAction<Number>> void test7_fakeImplementationsOfGenericInterface() {
509         GenericIAction<Number> actionNumber = new GenericIAction<Number>() {
510             @Override
511             public Number perform(Number n) {
512                 return n.intValue() + 1;
513             }
514         };
515 
516         GenericIAction<Integer> actionInt = new GenericIAction<Integer>() {
517             @Override
518             public Integer perform(Integer n) {
519                 return n + 1;
520             }
521         };
522 
523         GenericIAction<Long> actionL = new GenericIAction<Long>() {
524             @Override
525             public Long perform(Long n) {
526                 return n + 2;
527             }
528         };
529 
530         new MockUp<M>() {
531             @Mock
532             Number perform(Number n) {
533                 return n.intValue() - 1;
534             }
535         };
536 
537         Number n = actionNumber.perform(1);
538         assertEquals(0, n); // mocked
539 
540         int i = actionInt.perform(2);
541         assertEquals(3, i); // not mocked
542 
543         long l = actionL.perform(3L);
544         assertEquals(5, l); // not mocked
545     }
546 
547     /**
548      * Test 8 exclude JRE classes from faking for safety.
549      *
550      * @param <R>
551      *            the generic type
552      *
553      * @throws Exception
554      *             the exception
555      */
556     @Test
557     <R extends Readable> void test8_excludeJREClassesFromFakingForSafety() throws Exception {
558         new MockUp<R>() {
559             @Mock
560             int read(CharBuffer cb) {
561                 return 123;
562             }
563         };
564 
565         CharBuffer buf = CharBuffer.allocate(10);
566         int r1 = new Readable() {
567             @Override
568             public int read(@NonNull CharBuffer cb) {
569                 return 1;
570             }
571         }.read(buf);
572         assertEquals(123, r1);
573 
574         int r2 = new StringReader("test").read(buf);
575         assertEquals(4, r2);
576     }
577 }