1 package mockit;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertFalse;
5 import static org.junit.jupiter.api.Assertions.assertNotNull;
6 import static org.junit.jupiter.api.Assertions.assertNull;
7 import static org.junit.jupiter.api.Assertions.assertSame;
8 import static org.junit.jupiter.api.Assertions.assertThrows;
9 import static org.junit.jupiter.api.Assertions.assertTrue;
10
11 import jakarta.faces.application.FacesMessage;
12
13 import java.lang.reflect.Method;
14
15 import javax.accessibility.AccessibleState;
16
17 import mockit.MoreFakingTest.ClassWithNested.Nested;
18
19 import org.junit.jupiter.api.Test;
20
21
22
23
24 @SuppressWarnings("JUnitTestMethodWithNoAssertions")
25 final class MoreFakingTest {
26
27
28 final CodeUnderTest codeUnderTest = new CodeUnderTest();
29
30
31 boolean fakeExecuted;
32
33
34
35
36 static class CodeUnderTest {
37
38
39 private final Collaborator dependency = new Collaborator();
40
41
42
43
44 void doSomething() {
45 dependency.provideSomeService();
46 }
47
48
49
50
51
52
53
54
55
56 long doSomethingElse(int i) {
57 return dependency.getThreadSpecificValue(i);
58 }
59 }
60
61
62
63
64 public static class Collaborator {
65
66
67 static Object xyz;
68
69
70 protected int value;
71
72
73
74
75 public Collaborator() {
76 }
77
78
79
80
81
82
83
84 Collaborator(int value) {
85 this.value = value;
86 }
87
88
89
90
91
92
93 @SuppressWarnings("DeprecatedIsStillUsed")
94 @Deprecated
95 protected static String doInternal() {
96 return "123";
97 }
98
99
100
101
102 public void provideSomeService() {
103 throw new RuntimeException("Real provideSomeService() called");
104 }
105
106
107
108
109
110
111 public int getValue() {
112 return value;
113 }
114
115
116
117
118
119
120
121 void setValue(int value) {
122 this.value = value;
123 }
124
125
126
127
128
129
130
131
132
133 protected long getThreadSpecificValue(int i) {
134 return Thread.currentThread().getId() + i;
135 }
136 }
137
138
139
140
141 static class FakeCollaborator1 extends MockUp<Collaborator> {
142
143
144
145
146 @Mock
147 void provideSomeService() {
148 }
149 }
150
151
152
153
154 @Test
155 void fakeDoingNothing() {
156 new FakeCollaborator1();
157
158 codeUnderTest.doSomething();
159 }
160
161
162
163
164 @Test
165 void applyFakesFromInnerFakeClassWithFakeConstructor() {
166 new FakeCollaborator4();
167 assertFalse(fakeExecuted);
168
169 new CodeUnderTest().doSomething();
170
171 assertTrue(fakeExecuted);
172 }
173
174
175
176
177 class FakeCollaborator4 extends MockUp<Collaborator> {
178
179
180
181
182 @Mock
183 void $init() {
184 fakeExecuted = true;
185 }
186
187
188
189
190 @Mock
191 void provideSomeService() {
192 }
193 }
194
195
196
197
198 @Test
199 public void applyReentrantFake() {
200 new FakeCollaboratorWithReentrantFakeMethod();
201
202 assertThrows(RuntimeException.class, () -> {
203 codeUnderTest.doSomething();
204 });
205 }
206
207
208
209
210 static class FakeCollaboratorWithReentrantFakeMethod extends MockUp<Collaborator> {
211
212
213
214
215
216
217 @Mock
218 int getValue() {
219 return 123;
220 }
221
222
223
224
225
226
227
228 @Mock
229 void provideSomeService(Invocation inv) {
230 inv.proceed();
231 }
232 }
233
234
235
236
237 @Test
238 void applyFakeForConstructor() {
239 new FakeCollaboratorWithConstructorFake();
240
241 new FacesMessage("test");
242 }
243
244
245
246
247 static class FakeCollaboratorWithConstructorFake extends MockUp<FacesMessage> {
248
249
250
251
252
253
254
255 @Mock
256 void $init(String value) {
257 assertEquals("test", value);
258 }
259 }
260
261
262
263
264 public static class SubCollaborator extends Collaborator {
265
266
267
268
269
270
271
272 public SubCollaborator(int i) {
273 throw new RuntimeException(String.valueOf(i));
274 }
275
276 @Override
277 public void provideSomeService() {
278 value = 123;
279 }
280 }
281
282
283
284
285 @Test
286 void applyFakeForClassHierarchy() {
287 new MockUp<SubCollaborator>() {
288 @Mock
289 void $init(Invocation inv, int i) {
290 assertNotNull(inv.getInvokedInstance());
291 assertTrue(i > 0);
292 }
293
294 @Mock
295 void provideSomeService(Invocation inv) {
296 SubCollaborator it = inv.getInvokedInstance();
297 it.value = 45;
298 }
299
300 @Mock
301 int getValue(Invocation inv) {
302 SubCollaborator it = inv.getInvokedInstance();
303 assertNotNull(it);
304 return 123;
305 }
306 };
307
308 SubCollaborator collaborator = new SubCollaborator(123);
309 collaborator.provideSomeService();
310 assertEquals(45, collaborator.value);
311 assertEquals(123, collaborator.getValue());
312 }
313
314
315
316
317 @Test
318 void applyFakeForJREClass() {
319 FakeThread fakeThread = new FakeThread();
320
321 Thread.currentThread().interrupt();
322
323 assertTrue(fakeThread.interrupted);
324 }
325
326
327
328
329 public static class FakeThread extends MockUp<Thread> {
330
331
332 boolean interrupted;
333
334
335
336
337 @Mock
338 public void interrupt() {
339 interrupted = true;
340 }
341 }
342
343
344
345
346 @Test
347 void fakeStaticInitializer() {
348 new MockUp<AccessibleState>() {
349 @Mock
350 void $clinit() {
351 }
352 };
353
354 assertNull(AccessibleState.ACTIVE);
355 }
356
357
358
359
360 abstract static class AnAbstractClass {
361
362
363
364
365
366 protected abstract int doSomething();
367 }
368
369
370
371
372
373
374
375 @Test
376 <A extends AnAbstractClass> void fakeAbstractClassWithFakeForAbstractMethodHavingInvocationParameter() {
377 final AnAbstractClass obj = new AnAbstractClass() {
378 @Override
379 protected int doSomething() {
380 return 0;
381 }
382 };
383
384 new MockUp<A>() {
385 @Mock
386 int doSomething(Invocation inv) {
387 assertSame(obj, inv.getInvokedInstance());
388 Method invokedMethod = inv.getInvokedMember();
389 assertTrue(AnAbstractClass.class.isAssignableFrom(invokedMethod.getDeclaringClass()));
390 return 123;
391 }
392 };
393
394 assertEquals(123, obj.doSomething());
395 }
396
397
398
399
400
401
402
403 static class GenericClass<T> {
404
405
406
407
408
409 protected T doSomething() {
410 return null;
411 }
412 }
413
414
415
416
417 @Test
418 void fakeGenericClassWithFakeHavingInvocationParameter() {
419 new MockUp<GenericClass<String>>() {
420 @Mock
421 String doSomething(Invocation inv) {
422 return "faked";
423 }
424 };
425
426 GenericClass<String> faked = new GenericClass<>();
427 assertEquals("faked", faked.doSomething());
428 }
429
430
431
432
433
434
435
436 @Test
437 @SuppressWarnings("MethodWithMultipleLoops")
438 void concurrentFake() throws Exception {
439 new MockUp<Collaborator>() {
440 @Mock
441 long getThreadSpecificValue(int i) {
442 return Thread.currentThread().getId() + 123;
443 }
444 };
445
446 Thread[] threads = new Thread[5];
447
448 for (int i = 0; i < threads.length; i++) {
449 threads[i] = new Thread() {
450 @Override
451 public void run() {
452 long threadSpecificValue = Thread.currentThread().getId() + 123;
453 long actualValue = new CodeUnderTest().doSomethingElse(0);
454 assertEquals(threadSpecificValue, actualValue);
455 }
456 };
457 }
458
459 for (Thread thread : threads) {
460 thread.start();
461 }
462 for (Thread thread : threads) {
463 thread.join();
464 }
465 }
466
467
468
469
470 @Test
471 void fakeAffectsInstancesOfSpecifiedSubclassAndNotOfBaseClass() {
472 new FakeForSubclass();
473
474
475 assertEquals(123, new SubCollaborator(5).getValue());
476
477
478
479 assertEquals("faked", Collaborator.doInternal());
480
481
482 assertEquals(62, new Collaborator(62).getValue());
483 }
484
485
486
487
488 static class FakeForSubclass extends MockUp<SubCollaborator> {
489
490
491
492
493
494
495
496 @Mock
497 void $init(int i) {
498 }
499
500
501
502
503
504
505 @Mock
506 String doInternal() {
507 return "faked";
508 }
509
510
511
512
513
514
515 @Mock
516 int getValue() {
517 return 123;
518 }
519 }
520
521
522
523
524 public static final class ClassWithNested {
525
526
527
528
529 public static void doSomething() {
530 }
531
532
533
534
535 public static final class Nested {
536 }
537 }
538
539
540
541
542 @Test
543 void fakeAClassHavingANestedClass() {
544 new MockUp<ClassWithNested>() {
545 @Mock
546 void doSomething() {
547 }
548 };
549
550 Class<?> outerClass = Nested.class.getDeclaringClass();
551
552 assertSame(ClassWithNested.class, outerClass);
553 }
554 }