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.assertNotSame;
11  import static org.junit.jupiter.api.Assertions.assertNull;
12  import static org.junit.jupiter.api.Assertions.assertSame;
13  import static org.junit.jupiter.api.Assertions.assertTrue;
14  import static org.junit.jupiter.api.Assertions.fail;
15  
16  import java.io.DataInputStream;
17  import java.io.File;
18  import java.io.FileInputStream;
19  import java.io.FileOutputStream;
20  import java.io.FileWriter;
21  import java.io.PrintWriter;
22  import java.io.Writer;
23  import java.nio.file.Path;
24  import java.time.Duration;
25  import java.util.Calendar;
26  import java.util.Date;
27  import java.util.GregorianCalendar;
28  import java.util.TimeZone;
29  import java.util.jar.Attributes;
30  import java.util.jar.JarEntry;
31  import java.util.jar.JarFile;
32  import java.util.jar.Manifest;
33  import java.util.logging.LogManager;
34  import java.util.logging.Logger;
35  
36  import mockit.integration.junit5.ExpectedException;
37  import mockit.integration.junit5.JMockitExtension;
38  
39  import org.junit.jupiter.api.Test;
40  import org.junit.jupiter.api.extension.ExtendWith;
41  
42  /**
43   * The Class JREMockingTest.
44   */
45  @ExtendWith(JMockitExtension.class)
46  class JREMockingTest {
47      // Mocking java.io.File
48      // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49  
50      /**
51       * Mocking of file.
52       *
53       * @param file
54       *            the file
55       */
56      @Test
57      void mockingOfFile(@Mocked final File file) {
58          new Expectations() {
59              {
60                  file.exists();
61                  result = true;
62              }
63          };
64  
65          File f = Path.of("...").toFile();
66          assertTrue(f.exists());
67      }
68  
69      /**
70       * Mocking file and recording expectation to match on specific constructor call.
71       *
72       * @param anyFile
73       *            the any file
74       */
75      @Test
76      void mockingFileAndRecordingExpectationToMatchOnSpecificConstructorCall(@Mocked File anyFile) {
77          new Expectations() {
78              {
79                  Path.of("a.txt").toFile().exists();
80                  result = true;
81              }
82          };
83  
84          boolean aExists = Path.of("a.txt").toFile().exists();
85          // noinspection TooBroadScope
86          boolean bExists = Path.of("b.txt").toFile().exists();
87  
88          assertTrue(aExists);
89          assertFalse(bExists);
90      }
91  
92      // Faking java.util.Calendar
93      // ///////////////////////////////////////////////////////////////////////////////////////////////////////////
94  
95      /**
96       * Faking of calendar.
97       */
98      @Test
99      void fakingOfCalendar() {
100         final Calendar calCST = new GregorianCalendar(2010, Calendar.MAY, 15);
101         final TimeZone tzCST = TimeZone.getTimeZone("CST");
102         new MockUp<Calendar>() {
103             @Mock
104             Calendar getInstance(Invocation inv, TimeZone tz) {
105                 return tz == tzCST ? calCST : inv.<Calendar> proceed();
106             }
107         };
108 
109         Calendar cal1 = Calendar.getInstance(tzCST);
110         assertSame(calCST, cal1);
111         assertEquals(2010, cal1.get(Calendar.YEAR));
112 
113         TimeZone tzPST = TimeZone.getTimeZone("PST");
114         Calendar cal2 = Calendar.getInstance(tzPST);
115         assertNotSame(calCST, cal2);
116     }
117 
118     // Mocking java.util.Date
119     // //////////////////////////////////////////////////////////////////////////////////////////////////////////////
120 
121     /**
122      * Regular mocking of annotated JRE method.
123      *
124      * @param d
125      *            the d
126      *
127      * @throws Exception
128      *             the exception
129      */
130     @Test
131     void regularMockingOfAnnotatedJREMethod(@Mocked Date d) throws Exception {
132         assertTrue(d.getClass().getDeclaredMethod("parse", String.class).isAnnotationPresent(Deprecated.class));
133     }
134 
135     /**
136      * Dynamic mocking of annotated JRE method.
137      *
138      * @throws Exception
139      *             the exception
140      */
141     @Test
142     @SuppressWarnings("deprecation")
143     void dynamicMockingOfAnnotatedJREMethod() throws Exception {
144         final Date d = new Date();
145 
146         new Expectations(d) {
147             {
148                 d.getMinutes();
149                 result = 5;
150             }
151         };
152 
153         assertEquals(5, d.getMinutes());
154         assertTrue(Date.class.getDeclaredMethod("getMinutes").isAnnotationPresent(Deprecated.class));
155     }
156 
157     // Mocking of IO classes
158     // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
159 
160     /** The stream. */
161     @Injectable
162     FileOutputStream stream;
163 
164     /** The writer. */
165     @Injectable
166     Writer writer;
167 
168     /**
169      * Dynamic mocking of file output stream through mock field.
170      *
171      * @throws Exception
172      *             the exception
173      */
174     @Test
175     void dynamicMockingOfFileOutputStreamThroughMockField() throws Exception {
176         new Expectations() {
177             {
178                 // noinspection ConstantConditions
179                 stream.write((byte[]) any);
180             }
181         };
182 
183         stream.write("Hello world".getBytes());
184         writer.append('x');
185 
186         new Verifications() {
187             {
188                 writer.append('x');
189             }
190         };
191     }
192 
193     // Un-mockable JRE classes
194     // /////////////////////////////////////////////////////////////////////////////////////////////////////////////
195 
196     /**
197      * Attempt to mock unmockable JRE class.
198      *
199      * @param unmockable
200      *            the unmockable
201      */
202     @Test
203     @ExpectedException(IllegalArgumentException.class)
204     void attemptToMockUnmockableJREClass(@Mocked FileInputStream unmockable) {
205         fail("Should never get here");
206     }
207 
208     /**
209      * Attempt to mock unmockable JRE class.
210      *
211      * @param unmockable
212      *            the unmockable
213      */
214     @Test
215     @ExpectedException(IllegalArgumentException.class)
216     void attemptToMockUnmockableJREClass(@Mocked FileOutputStream unmockable) {
217         fail("Should never get here");
218     }
219 
220     /**
221      * Attempt to mock unmockable JRE class.
222      *
223      * @param unmockable
224      *            the unmockable
225      */
226     @Test
227     @ExpectedException(IllegalArgumentException.class)
228     void attemptToMockUnmockableJREClass(@Mocked Writer unmockable) {
229         fail("Should never get here");
230     }
231 
232     /**
233      * Attempt to mock unmockable JRE class.
234      *
235      * @param unmockable
236      *            the unmockable
237      */
238     @Test
239     @ExpectedException(IllegalArgumentException.class)
240     void attemptToMockUnmockableJREClass(@Mocked FileWriter unmockable) {
241         fail("Should never get here");
242     }
243 
244     /**
245      * Attempt to mock unmockable JRE class.
246      *
247      * @param unmockable
248      *            the unmockable
249      */
250     @Test
251     @ExpectedException(IllegalArgumentException.class)
252     void attemptToMockUnmockableJREClass(@Mocked PrintWriter unmockable) {
253         fail("Should never get here");
254     }
255 
256     /**
257      * Attempt to mock unmockable JRE class.
258      *
259      * @param unmockable
260      *            the unmockable
261      */
262     @Test
263     @ExpectedException(IllegalArgumentException.class)
264     void attemptToMockUnmockableJREClass(@Mocked DataInputStream unmockable) {
265         fail("Should never get here");
266     }
267 
268     /**
269      * Attempt to mock unmockable JRE class.
270      *
271      * @param unmockable
272      *            the unmockable
273      */
274     @Test
275     @ExpectedException(IllegalArgumentException.class)
276     void attemptToMockUnmockableJREClass(@Mocked StringBuffer unmockable) {
277         fail("Should never get here");
278     }
279 
280     /**
281      * Attempt to mock unmockable JRE class.
282      *
283      * @param unmockable
284      *            the unmockable
285      */
286     @Test
287     @ExpectedException(IllegalArgumentException.class)
288     void attemptToMockUnmockableJREClass(@Mocked StringBuilder unmockable) {
289         fail("Should never get here");
290     }
291 
292     /**
293      * Attempt to mock unmockable JRE class.
294      *
295      * @param unmockable
296      *            the unmockable
297      */
298     @Test
299     @ExpectedException(IllegalArgumentException.class)
300     void attemptToMockUnmockableJREClass(@Mocked Exception unmockable) {
301         fail("Should never get here");
302     }
303 
304     /**
305      * Attempt to mock unmockable JRE class.
306      *
307      * @param unmockable
308      *            the unmockable
309      */
310     @Test
311     @ExpectedException(IllegalArgumentException.class)
312     void attemptToMockUnmockableJREClass(@Mocked Throwable unmockable) {
313         fail("Should never get here");
314     }
315 
316     /**
317      * Attempt to mock unmockable JRE class.
318      *
319      * @param unmockable
320      *            the unmockable
321      */
322     @Test
323     @ExpectedException(IllegalArgumentException.class)
324     void attemptToMockUnmockableJREClass(@Mocked Thread unmockable) {
325         fail("Should never get here");
326     }
327 
328     /**
329      * Attempt to mock unmockable JRE class.
330      *
331      * @param unmockable
332      *            the unmockable
333      */
334     @Test
335     @ExpectedException(IllegalArgumentException.class)
336     void attemptToMockUnmockableJREClass(@Mocked ThreadLocal<?> unmockable) {
337         fail("Should never get here");
338     }
339 
340     /**
341      * Attempt to mock unmockable JRE class.
342      *
343      * @param unmockable
344      *            the unmockable
345      */
346     @Test
347     @ExpectedException(IllegalArgumentException.class)
348     void attemptToMockUnmockableJREClass(@Mocked ClassLoader unmockable) {
349         fail("Should never get here");
350     }
351 
352     /**
353      * Attempt to mock unmockable JRE class.
354      *
355      * @param unmockable
356      *            the unmockable
357      */
358     @Test
359     @ExpectedException(IllegalArgumentException.class)
360     void attemptToMockUnmockableJREClass(@Mocked Class<?> unmockable) {
361         fail("Should never get here");
362     }
363 
364     /**
365      * Attempt to mock unmockable JRE class.
366      *
367      * @param unmockable
368      *            the unmockable
369      */
370     @Test
371     @ExpectedException(IllegalArgumentException.class)
372     void attemptToMockUnmockableJREClass(@Mocked Math unmockable) {
373         fail("Should never get here");
374     }
375 
376     /**
377      * Attempt to mock unmockable JRE class.
378      *
379      * @param unmockable
380      *            the unmockable
381      */
382     @Test
383     @ExpectedException(IllegalArgumentException.class)
384     void attemptToMockUnmockableJREClass(@Mocked StrictMath unmockable) {
385         fail("Should never get here");
386     }
387 
388     /**
389      * Attempt to mock unmockable JRE class.
390      *
391      * @param unmockable
392      *            the unmockable
393      */
394     @Test
395     @ExpectedException(IllegalArgumentException.class)
396     void attemptToMockUnmockableJREClass(@Mocked Object unmockable) {
397         fail("Should never get here");
398     }
399 
400     /**
401      * Attempt to mock unmockable JRE class.
402      *
403      * @param unmockable
404      *            the unmockable
405      */
406     @Test
407     @ExpectedException(IllegalArgumentException.class)
408     void attemptToMockUnmockableJREClass(@Mocked Enum<?> unmockable) {
409         fail("Should never get here");
410     }
411 
412     /**
413      * Attempt to mock unmockable JRE class.
414      *
415      * @param unmockable
416      *            the unmockable
417      */
418     @Test
419     @ExpectedException(IllegalArgumentException.class)
420     void attemptToMockUnmockableJREClass(@Mocked System unmockable) {
421         fail("Should never get here");
422     }
423 
424     /**
425      * Attempt to mock unmockable JRE class.
426      *
427      * @param unmockable
428      *            the unmockable
429      */
430     @Test
431     @ExpectedException(IllegalArgumentException.class)
432     void attemptToMockUnmockableJREClass(@Mocked JarFile unmockable) {
433         fail("Should never get here");
434     }
435 
436     /**
437      * Attempt to mock unmockable JRE class.
438      *
439      * @param unmockable
440      *            the unmockable
441      */
442     @Test
443     @ExpectedException(IllegalArgumentException.class)
444     void attemptToMockUnmockableJREClass(@Mocked JarEntry unmockable) {
445         fail("Should never get here");
446     }
447 
448     /**
449      * Attempt to mock unmockable JRE class.
450      *
451      * @param unmockable
452      *            the unmockable
453      */
454     @Test
455     @ExpectedException(IllegalArgumentException.class)
456     void attemptToMockUnmockableJREClass(@Mocked Manifest unmockable) {
457         fail("Should never get here");
458     }
459 
460     /**
461      * Attempt to mock unmockable JRE class.
462      *
463      * @param unmockable
464      *            the unmockable
465      */
466     @Test
467     @ExpectedException(IllegalArgumentException.class)
468     void attemptToMockUnmockableJREClass(@Mocked Attributes unmockable) {
469         fail("Should never get here");
470     }
471 
472     /**
473      * Attempt to mock unmockable JRE class.
474      *
475      * @param unmockable
476      *            the unmockable
477      */
478     @Test
479     @ExpectedException(IllegalArgumentException.class)
480     void attemptToMockUnmockableJREClass(@SuppressWarnings("Since15") @Mocked Duration unmockable) {
481         fail("Should never get here");
482     }
483 
484     // Mocking java.time
485     // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
486 
487     /**
488      * The Interface DurationProvider.
489      */
490     public interface DurationProvider {
491         /**
492          * Gets the duration.
493          *
494          * @return the duration
495          */
496         @SuppressWarnings("Since15")
497         Duration getDuration();
498     }
499 
500     /**
501      * Mock method which returns A duration.
502      *
503      * @param mock
504      *            the mock
505      */
506     @Test
507     void mockMethodWhichReturnsADuration(@Mocked DurationProvider mock) {
508         Object d = mock.getDuration();
509 
510         assertNull(d);
511     }
512 
513     // Mocking java.util.logging
514     // ///////////////////////////////////////////////////////////////////////////////////////////////////////////
515 
516     /**
517      * Mock log manager.
518      *
519      * @param mock
520      *            the mock
521      */
522     @Test
523     void mockLogManager(@Mocked LogManager mock) {
524         LogManager logManager = LogManager.getLogManager();
525         // noinspection MisorderedAssertEqualsArguments
526         assertSame(mock, logManager);
527     }
528 
529     /**
530      * Mock logger.
531      *
532      * @param mock
533      *            the mock
534      */
535     @Test
536     void mockLogger(@Mocked Logger mock) {
537         // TODO: this call causes Surefire to fail: assertNotNull(LogManager.getLogManager());
538         // noinspection MisorderedAssertEqualsArguments
539         assertSame(mock, Logger.getLogger("test"));
540     }
541 }