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.assertNotNull;
10  import static org.junit.jupiter.api.Assertions.assertNull;
11  import static org.junit.jupiter.api.Assertions.assertSame;
12  
13  import java.lang.annotation.RetentionPolicy;
14  import java.util.concurrent.TimeUnit;
15  
16  import mockit.integration.junit5.JMockitExtension;
17  
18  import org.junit.jupiter.api.Test;
19  import org.junit.jupiter.api.extension.ExtendWith;
20  
21  /**
22   * The Class MockedEnumsTest.
23   */
24  @ExtendWith(JMockitExtension.class)
25  class MockedEnumsTest {
26  
27      /**
28       * The Enum MyEnum.
29       */
30      enum MyEnum {
31  
32          /** The First. */
33          First(true, 10, "First"),
34  
35          /** The Second. */
36          Second(false, 6, "Second");
37  
38          /** The flag. */
39          private final boolean flag;
40  
41          /** The num. */
42          private final int num;
43  
44          /** The desc. */
45          private final String desc;
46  
47          /**
48           * Instantiates a new my enum.
49           *
50           * @param flag
51           *            the flag
52           * @param num
53           *            the num
54           * @param desc
55           *            the desc
56           */
57          MyEnum(boolean flag, int num, String desc) {
58              this.flag = flag;
59              this.num = num;
60              this.desc = desc;
61          }
62  
63          /**
64           * Gets the value.
65           *
66           * @param f
67           *            the f
68           *
69           * @return the value
70           */
71          public double getValue(double f) {
72              return f * num;
73          }
74  
75          /**
76           * Gets the description.
77           *
78           * @return the description
79           */
80          public String getDescription() {
81              return num + desc + flag;
82          }
83      }
84  
85      /**
86       * One enum being mocked must not affect other enums.
87       *
88       * @param e
89       *            the e
90       */
91      @Test
92      void oneEnumBeingMockedMustNotAffectOtherEnums(@Mocked MyEnum e) {
93          assertNotNull(RetentionPolicy.valueOf("RUNTIME"));
94      }
95  
96      /**
97       * Mock enum values.
98       *
99       * @param mock
100      *            the mock
101      */
102     @Test
103     void mockEnumValues(@Mocked final MyEnum mock) {
104         new Expectations() {
105             {
106                 MyEnum.values();
107                 result = new MyEnum[] { mock };
108                 mock.getValue(anyDouble);
109                 result = 50.0;
110             }
111         };
112 
113         MyEnum[] values = MyEnum.values();
114         assertEquals(1, values.length);
115 
116         double value = values[0].getValue(0.5);
117         assertEquals(50.0, value, 0.0);
118     }
119 
120     /**
121      * Mock instance method on any enum element.
122      *
123      * @param anyEnum
124      *            the any enum
125      */
126     @Test
127     void mockInstanceMethodOnAnyEnumElement(@Mocked final MyEnum anyEnum) {
128         final double f = 2.5;
129 
130         new Expectations() {
131             {
132                 anyEnum.getValue(f);
133                 result = 12.3;
134             }
135         };
136 
137         assertEquals(12.3, MyEnum.First.getValue(f), 0.0);
138         assertEquals(12.3, MyEnum.Second.getValue(f), 0.0);
139     }
140 
141     /**
142      * Verify instance method invocation on any enum element.
143      *
144      * @param anyEnum
145      *            the any enum
146      */
147     @Test
148     void verifyInstanceMethodInvocationOnAnyEnumElement(@Mocked MyEnum anyEnum) {
149         assertNull(MyEnum.First.getDescription());
150         assertNull(MyEnum.Second.getDescription());
151         assertNull(anyEnum.getDescription());
152 
153         new Verifications() {
154             {
155                 MyEnum.Second.getDescription();
156                 times = 1;
157             }
158         };
159     }
160 
161     /**
162      * Mock specific enum elements by using two mock instances.
163      *
164      * @param mock1
165      *            the mock 1
166      * @param mock2
167      *            the mock 2
168      */
169     @Test
170     void mockSpecificEnumElementsByUsingTwoMockInstances(@Mocked MyEnum mock1, @Mocked MyEnum mock2) {
171         new Expectations() {
172             {
173                 MyEnum.First.getValue(anyDouble);
174                 result = 12.3;
175                 MyEnum.Second.getValue(anyDouble);
176                 result = -5.01;
177             }
178         };
179 
180         assertEquals(12.3, MyEnum.First.getValue(2.5), 0.0);
181         assertEquals(-5.01, MyEnum.Second.getValue(1), 0.0);
182     }
183 
184     /**
185      * Mock specific enum elements even when using A single mock instance.
186      *
187      * @param unused
188      *            the unused
189      */
190     @Test
191     void mockSpecificEnumElementsEvenWhenUsingASingleMockInstance(@Mocked MyEnum unused) {
192         new Expectations() {
193             {
194                 MyEnum.First.getValue(anyDouble);
195                 result = 12.3;
196                 MyEnum.Second.getValue(anyDouble);
197                 result = -5.01;
198             }
199         };
200 
201         assertEquals(-5.01, MyEnum.Second.getValue(1), 0.0);
202         assertEquals(12.3, MyEnum.First.getValue(2.5), 0.0);
203 
204         new Verifications() {
205             {
206                 MyEnum.First.getValue(2.5);
207                 MyEnum.Second.getValue(1);
208             }
209         };
210     }
211 
212     /**
213      * Mock non abstract methods in enum with abstract method.
214      *
215      * @param tm
216      *            the tm
217      *
218      * @throws Exception
219      *             the exception
220      */
221     @Test
222     void mockNonAbstractMethodsInEnumWithAbstractMethod(@Mocked final TimeUnit tm) throws Exception {
223         new Expectations() {
224             {
225                 tm.convert(anyLong, TimeUnit.SECONDS);
226                 result = 1L;
227                 tm.sleep(anyLong);
228             }
229         };
230 
231         assertEquals(1, tm.convert(1000, TimeUnit.SECONDS));
232         tm.sleep(10000);
233     }
234 
235     /**
236      * The Enum EnumWithValueSpecificMethods.
237      */
238     public enum EnumWithValueSpecificMethods {
239 
240         /** The One. */
241         One {
242             @Override
243             public int getValue() {
244                 return 1;
245             }
246 
247             @Override
248             public String getDescription() {
249                 return "one";
250             }
251         },
252 
253         /** The Two. */
254         Two {
255             @Override
256             public int getValue() {
257                 return 2;
258             }
259 
260             @Override
261             public String getDescription() {
262                 return "two";
263             }
264         };
265 
266         /**
267          * Gets the value.
268          *
269          * @return the value
270          */
271         public abstract int getValue();
272 
273         /**
274          * Gets the description.
275          *
276          * @return the description
277          */
278         @SuppressWarnings("unused")
279         public String getDescription() {
280             return String.valueOf(getValue());
281         }
282     }
283 
284     /**
285      * Mock enum with value specific methods.
286      *
287      * @param mockedEnum
288      *            the mocked enum
289      */
290     @Test
291     void mockEnumWithValueSpecificMethods(@Mocked EnumWithValueSpecificMethods mockedEnum) {
292         new Expectations() {
293             {
294                 EnumWithValueSpecificMethods.One.getValue();
295                 result = 123;
296                 EnumWithValueSpecificMethods.Two.getValue();
297                 result = -45;
298 
299                 EnumWithValueSpecificMethods.One.getDescription();
300                 result = "1";
301                 EnumWithValueSpecificMethods.Two.getDescription();
302                 result = "2";
303             }
304         };
305 
306         assertEquals(123, EnumWithValueSpecificMethods.One.getValue());
307         assertEquals(-45, EnumWithValueSpecificMethods.Two.getValue());
308         assertEquals("1", EnumWithValueSpecificMethods.One.getDescription());
309         assertEquals("2", EnumWithValueSpecificMethods.Two.getDescription());
310     }
311 
312     /**
313      * The Enum Foo.
314      */
315     enum Foo {
316         /** The foo. */
317         FOO;
318 
319         /**
320          * Value.
321          *
322          * @return the string
323          */
324         String value() {
325             return "foo";
326         }
327     }
328 
329     /**
330      * The Interface InterfaceWhichReturnsAnEnum.
331      */
332     interface InterfaceWhichReturnsAnEnum {
333         /**
334          * Gets the foo.
335          *
336          * @return the foo
337          */
338         Foo getFoo();
339     }
340 
341     /**
342      * Cascaded enum.
343      *
344      * @param mock
345      *            the mock
346      */
347     @Test
348     void cascadedEnum(@Mocked final InterfaceWhichReturnsAnEnum mock) {
349         final Foo foo = Foo.FOO;
350 
351         new Expectations() {
352             {
353                 mock.getFoo();
354                 result = foo;
355             }
356         };
357 
358         Foo cascadedFoo = mock.getFoo();
359         assertSame(foo, cascadedFoo);
360         assertEquals("foo", foo.value());
361     }
362 }