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