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.assertNotNull;
11  import static org.junit.jupiter.api.Assertions.assertNotSame;
12  import static org.junit.jupiter.api.Assertions.assertSame;
13  import static org.junit.jupiter.api.Assertions.assertTrue;
14  
15  import java.awt.BasicStroke;
16  import java.io.Reader;
17  import java.util.ArrayList;
18  import java.util.List;
19  import java.util.concurrent.Callable;
20  
21  import org.junit.jupiter.api.Test;
22  
23  public final class MockUpForSingleClassInstanceTest {
24      public static class AClass {
25          final int numericValue;
26          final String textValue;
27  
28          AClass(int n) {
29              this(n, null);
30          }
31  
32          AClass(int n, String s) {
33              numericValue = n;
34              textValue = s;
35          }
36  
37          public final int getNumericValue() {
38              return numericValue;
39          }
40  
41          public String getTextValue() {
42              return textValue;
43          }
44  
45          protected final int getSomeOtherValue() {
46              return 0;
47          }
48  
49          public static boolean doSomething() {
50              return false;
51          }
52      }
53  
54      @Test
55      public void multipleMockupsOfSameTypeWithOwnMockInstanceEach() {
56          final class AClassMockUp extends MockUp<AClass> {
57              private final int number;
58              private final String text;
59  
60              AClassMockUp(int number, String text) {
61                  this.number = number;
62                  this.text = text;
63              }
64  
65              @Mock
66              int getNumericValue() {
67                  return number;
68              }
69  
70              @Mock
71              String getTextValue() {
72                  return text;
73              }
74          }
75  
76          MockUp<AClass> mockUp1 = new AClassMockUp(1, "one");
77          AClass mock1 = mockUp1.getMockInstance();
78  
79          AClassMockUp mockUp2 = new AClassMockUp(2, "two");
80          AClass mock2 = mockUp2.getMockInstance();
81  
82          assertNotSame(mock1, mock2);
83          assertEquals(1, mock1.getNumericValue());
84          assertEquals("one", mock1.getTextValue());
85          assertEquals(0, mock1.getSomeOtherValue());
86          assertEquals(2, mock2.getNumericValue());
87          assertEquals("two", mock2.getTextValue());
88          assertEquals(0, mock2.getSomeOtherValue());
89          assertEquals("two", mock2.getTextValue());
90      }
91  
92      public static class AClassMockUp extends MockUp<BasicStroke> {
93          private final int value;
94  
95          AClassMockUp(int value) {
96              this.value = value;
97          }
98  
99          @Mock
100         public float getLineWidth() {
101             return value;
102         }
103     }
104 
105     @Test
106     public void samePublicMockupAppliedMultipleTimes() {
107         BasicStroke mock1 = new AClassMockUp(1).getMockInstance();
108         BasicStroke mock2 = new AClassMockUp(2).getMockInstance();
109 
110         assertNotSame(mock1, mock2);
111         assertEquals(1, mock1.getLineWidth(), 0);
112         assertEquals(2, mock2.getLineWidth(), 0);
113     }
114 
115     @Test
116     public void sameAnonymousMockupAppliedMultipleTimesWithDifferentTargetInstances() {
117         List<BasicStroke> targetInstances = new ArrayList<>();
118 
119         for (int i = 1; i <= 2; i++) {
120             final int width = 100 * i;
121             BasicStroke targetInstance = new BasicStroke(i);
122             new MockUp<BasicStroke>(targetInstance) {
123                 @Mock
124                 float getLineWidth() {
125                     return width;
126                 }
127             };
128             targetInstances.add(targetInstance);
129         }
130 
131         assertEquals(100, targetInstances.get(0).getLineWidth(), 0);
132         assertEquals(200, targetInstances.get(1).getLineWidth(), 0);
133     }
134 
135     @Test
136     public void sameAnonymousMockupAppliedMultipleTimesWithoutTargetInstanceButWithMockInstanceCreatedFromMockup() {
137         List<BasicStroke> mockInstances = new ArrayList<>();
138 
139         for (int i = 1; i <= 2; i++) {
140             final int width = 100 * i;
141             BasicStroke mockInstance = new MockUp<BasicStroke>() {
142                 @Mock
143                 float getLineWidth() {
144                     return width;
145                 }
146             }.getMockInstance();
147             mockInstances.add(mockInstance);
148         }
149 
150         assertEquals(100, mockInstances.get(0).getLineWidth(), 0);
151         assertEquals(200, mockInstances.get(1).getLineWidth(), 0);
152     }
153 
154     @Test
155     public void getMockInstanceFromInsideMockMethodForNonStaticMockedMethod() {
156         new MockUp<AClass>() {
157             @Mock
158             String getTextValue() {
159                 assertNotNull(getMockInstance());
160                 return "mock";
161             }
162         };
163 
164         assertEquals("mock", new AClass(123).getTextValue());
165     }
166 
167     @Test
168     public void mockupAffectingOneInstanceButNotOthersOfSameClass() {
169         AClass instance1 = new AClass(1);
170         AClass instance2 = new AClass(2);
171 
172         AClass mockInstance = new MockUp<AClass>(instance1) {
173             @Mock
174             int getNumericValue() {
175                 return 3;
176             }
177         }.getMockInstance();
178 
179         assertSame(instance1, mockInstance);
180         assertEquals(3, instance1.getNumericValue());
181         assertEquals(2, instance2.getNumericValue());
182         assertEquals(1, new AClass(1).getNumericValue());
183     }
184 
185     @Test
186     public void accessCurrentMockedInstanceFromInsideMockMethodForAnyInstanceOfTheMockedClass() {
187         AClass instance1 = new AClass(1);
188         AClass instance2 = new AClass(2, "test2");
189 
190         MockUp<AClass> mockUp = new MockUp<AClass>() {
191             @Mock
192             String getTextValue() {
193                 AClass mockedInstance = getMockInstance();
194                 return "mocked: " + mockedInstance.textValue;
195             }
196         };
197 
198         AClass instance3 = new AClass(3, "test3");
199         assertEquals("mocked: null", instance1.getTextValue());
200         assertEquals("mocked: test2", instance2.getTextValue());
201         assertEquals("mocked: test3", instance3.getTextValue());
202         assertSame(instance3, mockUp.getMockInstance());
203     }
204 
205     @Test
206     public void accessCurrentMockedInstanceFromInsideMockMethodForSingleMockedInstance() {
207         AClass unmockedInstance1 = new AClass(1, "test1");
208         final int i = 123;
209 
210         MockUp<AClass> mockUp = new MockUp<AClass>() {
211             final int numericValue = i;
212 
213             @Mock
214             String getTextValue() {
215                 AClass mockedInstance = getMockInstance();
216                 return "mocked: " + mockedInstance.textValue;
217             }
218 
219             @Mock
220             int getNumericValue() {
221                 return numericValue;
222             }
223         };
224         AClass onlyInstanceToBeMocked = mockUp.getMockInstance();
225 
226         assertEquals("test1", unmockedInstance1.getTextValue());
227         AClass unmockedInstance2 = new AClass(2, "test2");
228         assertEquals("mocked: null", onlyInstanceToBeMocked.getTextValue());
229         assertEquals("test2", unmockedInstance2.getTextValue());
230         assertSame(onlyInstanceToBeMocked, mockUp.getMockInstance());
231     }
232 
233     static final class ASubClass extends AClass {
234         ASubClass(int n, String s) {
235             super(n, s);
236         }
237 
238         @Override
239         public String getTextValue() {
240             return "subtext";
241         }
242     }
243 
244     @Test
245     public void applyMockupWithGivenSubclassInstance() {
246         AClass realInstance = new ASubClass(123, "test");
247 
248         MockUp<AClass> mockUp = new MockUp<AClass>(realInstance) {
249             @Mock
250             String getTextValue() {
251                 return "mock";
252             }
253 
254             @Mock
255             int getSomeOtherValue() {
256                 return 45;
257             }
258         };
259 
260         AClass mockInstance = mockUp.getMockInstance();
261         assertSame(realInstance, mockInstance);
262 
263         assertEquals(123, realInstance.getNumericValue());
264         assertEquals("mock", mockInstance.getTextValue());
265         assertEquals(45, mockInstance.getSomeOtherValue());
266     }
267 
268     public abstract static class AbstractBase implements Runnable {
269         protected abstract String getValue();
270 
271         public abstract void doSomething(int i);
272 
273         public boolean doSomethingElse() {
274             return true;
275         }
276     }
277 
278     @Test
279     public void getMockInstanceFromMockupForAbstractClass() {
280         MockUp<AbstractBase> mockUp = new MockUp<AbstractBase>() {
281             @Mock
282             String getValue() {
283                 AbstractBase mockInstance = getMockInstance();
284                 assertNotNull(mockInstance);
285                 return "test";
286             }
287 
288             @Mock
289             boolean doSomethingElse() {
290                 return false;
291             }
292         };
293 
294         AbstractBase mock = mockUp.getMockInstance();
295 
296         assertEquals("test", mock.getValue());
297         mock.doSomething(123);
298         mock.run();
299         assertFalse(mock.doSomethingElse());
300         assertSame(mock, mockUp.getMockInstance());
301     }
302 
303     public abstract static class GenericAbstractBase<T, N extends Number> implements Callable<N> {
304         protected abstract int doSomething(String s, T value);
305     }
306 
307     @Test
308     public void getMockInstanceFromMockupForAbstractJREClass() throws Exception {
309         MockUp<Reader> mockUp = new MockUp<Reader>() {
310             @Mock
311             int read(char[] cbuf, int off, int len) {
312                 Reader mockInstance = getMockInstance();
313                 assertNotNull(mockInstance);
314                 return 123;
315             }
316 
317             @Mock
318             boolean ready() {
319                 return true;
320             }
321         };
322 
323         Reader mock = mockUp.getMockInstance();
324 
325         assertEquals(123, mock.read(new char[0], 0, 0));
326         mock.close();
327         assertTrue(mock.ready());
328         assertSame(mock, mockUp.getMockInstance());
329     }
330 }