1
2
3
4
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.assertThrows;
12 import static org.junit.jupiter.api.Assertions.assertTrue;
13 import static org.junit.jupiter.api.Assertions.fail;
14
15 import java.io.File;
16 import java.io.FileNotFoundException;
17 import java.nio.file.Path;
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.junit.jupiter.api.Test;
22
23
24
25
26 class FakeInvocationProceedTest {
27
28
29
30
31 public static class BaseClassToBeFaked {
32
33
34 protected String name;
35
36
37
38
39
40
41
42
43
44 public final int baseMethod(int i) {
45 return i + 1;
46 }
47
48
49
50
51
52
53
54
55
56 protected int methodToBeFaked(int i) {
57 return i;
58 }
59 }
60
61
62
63
64 public static class ClassToBeFaked extends BaseClassToBeFaked {
65
66
67
68
69 public ClassToBeFaked() {
70 name = "";
71 }
72
73
74
75
76
77
78
79 public ClassToBeFaked(String name) {
80 this.name = name;
81 }
82
83
84
85
86
87
88 public boolean methodToBeFaked() {
89 return true;
90 }
91
92
93
94
95
96
97
98
99
100
101
102 protected int methodToBeFaked(int i, Object... args) {
103 int result = i;
104
105 for (Object arg : args) {
106 if (arg != null) {
107 result++;
108 }
109 }
110
111 return result;
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public String anotherMethodToBeFaked(String s, boolean b, List<Integer> ints) {
127 return (b ? s.toUpperCase() : s.toLowerCase()) + ints;
128 }
129
130
131
132
133
134
135
136
137
138 public static boolean staticMethodToBeFaked() throws FileNotFoundException {
139 throw new FileNotFoundException();
140 }
141
142
143
144
145 protected static native void nativeMethod();
146 }
147
148
149
150
151 @Test
152 void proceedFromFakeMethodWithoutParameters() {
153 new MockUp<ClassToBeFaked>() {
154 @Mock
155 boolean methodToBeMocked(Invocation inv) {
156 return inv.proceed();
157 }
158 };
159
160 assertTrue(new ClassToBeFaked().methodToBeFaked());
161 }
162
163
164
165
166 @Test
167 void proceedFromFakeMethodWithParameters() {
168 new MockUp<ClassToBeFaked>() {
169 @Mock
170 int methodToBeFaked(Invocation inv, int i) {
171 Integer j = inv.proceed();
172 return j + 1;
173 }
174
175 @Mock
176 private int methodToBeFaked(Invocation inv, int i, Object... args) {
177 args[2] = "mock";
178 return inv.<Integer> proceed();
179 }
180 };
181
182 ClassToBeFaked faked = new ClassToBeFaked();
183
184 assertEquals(124, faked.methodToBeFaked(123));
185 assertEquals(-8, faked.methodToBeFaked(-9));
186 assertEquals(7, faked.methodToBeFaked(3, "Test", new Object(), null, 45));
187 }
188
189
190
191
192 @Test
193 void proceedConditionallyFromFakeMethod() {
194 new MockUp<ClassToBeFaked>() {
195 @Mock
196 String anotherMethodToBeFaked(Invocation inv, String s, boolean b, List<Number> ints) {
197 if (!b) {
198 return s;
199 }
200
201 ints.add(45);
202 return inv.proceed();
203 }
204 };
205
206 ClassToBeFaked mocked = new ClassToBeFaked();
207
208
209 assertNull(mocked.anotherMethodToBeFaked(null, false, null));
210
211
212 List<Integer> values = new ArrayList<>();
213 assertEquals("TEST[45]", mocked.anotherMethodToBeFaked("test", true, values));
214
215
216 assertEquals("No proceed", mocked.anotherMethodToBeFaked("No proceed", false, null));
217 }
218
219
220
221
222
223
224
225 @Test
226 void proceedFromFakeMethodWhichThrowsCheckedException() throws Exception {
227 new MockUp<ClassToBeFaked>() {
228 @Mock
229 boolean staticMethodToBeFaked(Invocation inv) throws Exception {
230 if (inv.getInvocationIndex() == 0) {
231 return inv.<Boolean> proceed();
232 }
233
234 throw new InterruptedException("fake");
235 }
236 };
237
238 try {
239 ClassToBeFaked.staticMethodToBeFaked();
240 fail();
241 } catch (FileNotFoundException ignored) {
242 }
243
244 assertThrows(InterruptedException.class, () -> {
245 ClassToBeFaked.staticMethodToBeFaked();
246 });
247 }
248
249
250
251
252 @Test
253 void proceedFromFakeMethodIntoRealMethodWithModifiedArguments() {
254 class FakeWhichModifiesArguments extends MockUp<ClassToBeFaked> {
255 @Mock
256 final int methodToBeFaked(Invocation invocation, int i) {
257 return invocation.<Integer> proceed(i + 2);
258 }
259 }
260
261 new FakeWhichModifiesArguments() {
262 @Mock
263 synchronized int methodToBeFaked(Invocation inv, int i, Object... args) {
264 Object[] newArgs = { 2, "3" };
265 return inv.<Integer> proceed(1, newArgs);
266 }
267 };
268
269 ClassToBeFaked faked = new ClassToBeFaked();
270 assertEquals(3, faked.methodToBeFaked(1));
271 assertEquals(3, faked.methodToBeFaked(-2, null, "Abc", true, 'a'));
272 }
273
274
275
276
277 @Test
278 void cannotProceedFromFakeMethodIntoNativeMethod() {
279 new MockUp<ClassToBeFaked>() {
280 @Mock
281 void nativeMethod(Invocation inv) {
282 inv.proceed();
283 fail("Should not get here");
284 }
285 };
286
287 Throwable throwable = assertThrows(UnsupportedOperationException.class, () -> {
288 ClassToBeFaked.nativeMethod();
289 });
290 assertEquals("Cannot proceed into real implementation of native method", throwable.getMessage());
291 }
292
293
294
295
296 @Test
297 void proceedFromFakeMethodIntoConstructor() {
298 new MockUp<ClassToBeFaked>() {
299 @Mock
300 void $init(Invocation inv) {
301 assertNotNull(inv.<ClassToBeFaked> getInvokedInstance());
302 inv.proceed();
303 }
304 };
305
306 ClassToBeFaked obj = new ClassToBeFaked();
307 assertEquals("", obj.name);
308 }
309
310
311
312
313 @Test
314 void proceedConditionallyFromFakeMethodIntoConstructor() {
315 new MockUp<ClassToBeFaked>() {
316 @Mock
317 void $init(Invocation inv, String name) {
318 assertNotNull(inv.getInvokedInstance());
319
320 if ("proceed".equals(name)) {
321 inv.proceed();
322 }
323 }
324 };
325
326 assertEquals("proceed", new ClassToBeFaked("proceed").name);
327 assertNull(new ClassToBeFaked("do not proceed").name);
328 }
329
330
331
332
333 @Test
334 void proceedConditionallyFromFakeMethodIntoJREConstructor() {
335 new MockUp<File>() {
336 @Mock
337 void $init(Invocation inv, String name) {
338 if ("proceed".equals(name)) {
339 inv.proceed();
340 }
341 }
342 };
343
344 assertEquals("proceed", Path.of("proceed").toFile().toString());
345 assertNull(Path.of("do not proceed").toFile().toString());
346 }
347
348
349
350
351 @Test
352 void proceedFromFakeMethodIntoMethodInheritedFromBaseClass() {
353 new MockUp<ClassToBeFaked>() {
354 @Mock
355 int baseMethod(Invocation inv, int i) {
356 return inv.proceed(i + 1);
357 }
358 };
359
360 assertEquals(3, new ClassToBeFaked().baseMethod(1));
361 }
362 }