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