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.internal.reflection;
7   
8   import static org.junit.jupiter.api.Assertions.assertNotNull;
9   import static org.junit.jupiter.api.Assertions.assertNull;
10  import static org.junit.jupiter.api.Assertions.assertThrows;
11  import static org.junit.jupiter.api.Assertions.assertTrue;
12  
13  import org.junit.jupiter.api.Test;
14  
15  final class ConstructorReflectionTest {
16  
17      static class SimpleClass {
18          final int value;
19  
20          public SimpleClass() {
21              value = 0;
22          }
23  
24          public SimpleClass(int value) {
25              this.value = value;
26          }
27  
28          public SimpleClass(String str) {
29              int parsedValue;
30              try {
31                  parsedValue = Integer.parseInt(str);
32              } catch (NumberFormatException e) {
33                  parsedValue = 0;
34              }
35              this.value = parsedValue;
36          }
37      }
38  
39      static class NoDefaultConstructor {
40          final int value;
41  
42          NoDefaultConstructor(int value) {
43              this.value = value;
44          }
45      }
46  
47      static class ThrowingConstructor {
48          ThrowingConstructor() {
49              throw new RuntimeException("constructor failed");
50          }
51      }
52  
53      static class ThrowingCheckedConstructor {
54          ThrowingCheckedConstructor(String s) throws Exception {
55              throw new Exception("checked: " + s);
56          }
57      }
58  
59      @Test
60      void findSpecifiedConstructorWithMatchingTypes() {
61          var ctor = ConstructorReflection.findSpecifiedConstructor(SimpleClass.class, new Class<?>[] { int.class });
62          assertNotNull(ctor);
63      }
64  
65      @Test
66      void findSpecifiedConstructorWithStringType() {
67          var ctor = ConstructorReflection.findSpecifiedConstructor(SimpleClass.class, new Class<?>[] { String.class });
68          assertNotNull(ctor);
69      }
70  
71      @Test
72      void findSpecifiedConstructorWithCheckedException() {
73          var ctor = ConstructorReflection.findSpecifiedConstructor(ThrowingCheckedConstructor.class,
74                  new Class<?>[] { String.class });
75          assertNotNull(ctor);
76      }
77  
78      @Test
79      void findSpecifiedConstructorNotFound() {
80          assertThrows(IllegalArgumentException.class, () -> ConstructorReflection
81                  .findSpecifiedConstructor(SimpleClass.class, new Class<?>[] { double.class }));
82      }
83  
84      @Test
85      void newInstanceUsingDefaultConstructorCreatesInstance() {
86          SimpleClass instance = ConstructorReflection.newInstanceUsingDefaultConstructor(SimpleClass.class);
87          assertNotNull(instance);
88      }
89  
90      @Test
91      void newInstanceUsingDefaultConstructorThrowsForMissingConstructor() {
92          assertThrows(RuntimeException.class,
93                  () -> ConstructorReflection.newInstanceUsingDefaultConstructor(NoDefaultConstructor.class));
94      }
95  
96      @Test
97      void newInstanceUsingDefaultConstructorThrowsForThrowingConstructor() {
98          assertThrows(RuntimeException.class,
99                  () -> ConstructorReflection.newInstanceUsingDefaultConstructor(ThrowingConstructor.class));
100     }
101 
102     @Test
103     void newInstanceUsingDefaultConstructorIfAvailableReturnsInstanceWhenExists() {
104         SimpleClass instance = ConstructorReflection.newInstanceUsingDefaultConstructorIfAvailable(SimpleClass.class);
105         assertNotNull(instance);
106     }
107 
108     @Test
109     void newInstanceUsingDefaultConstructorIfAvailableReturnsNullWhenNoDefault() {
110         NoDefaultConstructor instance = ConstructorReflection
111                 .newInstanceUsingDefaultConstructorIfAvailable(NoDefaultConstructor.class);
112         assertNull(instance);
113     }
114 
115     @Test
116     void newInstanceUsingPublicConstructorIfAvailableReturnsInstanceWhenExists() {
117         SimpleClass instance = ConstructorReflection.newInstanceUsingPublicConstructorIfAvailable(SimpleClass.class,
118                 new Class<?>[] { int.class }, 42);
119         assertNotNull(instance);
120     }
121 
122     @Test
123     void newInstanceUsingPublicConstructorIfAvailableReturnsNullWhenNotFound() {
124         SimpleClass instance = ConstructorReflection.newInstanceUsingPublicConstructorIfAvailable(SimpleClass.class,
125                 new Class<?>[] { double.class }, 3.14);
126         assertNull(instance);
127     }
128 
129     @Test
130     void newInstanceUsingPublicDefaultConstructorCreatesInstance() {
131         SimpleClass instance = ConstructorReflection.newInstanceUsingPublicDefaultConstructor(SimpleClass.class);
132         assertNotNull(instance);
133     }
134 
135     @Test
136     void newInstanceUsingPublicDefaultConstructorThrowsWhenNoDefault() {
137         assertThrows(RuntimeException.class,
138                 () -> ConstructorReflection.newInstanceUsingPublicDefaultConstructor(NoDefaultConstructor.class));
139     }
140 
141     @Test
142     void newUninitializedInstanceCreatesInstance() {
143         NoDefaultConstructor instance = ConstructorReflection.newUninitializedInstance(NoDefaultConstructor.class);
144         assertNotNull(instance);
145     }
146 
147     @Test
148     void newInstanceUsingCompatibleConstructorCreatesInstance() throws ReflectiveOperationException {
149         ConstructorReflection.newInstanceUsingCompatibleConstructor(SimpleClass.class, "42");
150         // No exception means success
151         assertTrue(true);
152     }
153 
154     @Test
155     void newInstanceUsingCompatibleConstructorThrowsForMissingStringCtor() {
156         assertThrows(ReflectiveOperationException.class,
157                 () -> ConstructorReflection.newInstanceUsingCompatibleConstructor(NoDefaultConstructor.class, "x"));
158     }
159 }