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