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.assertTrue;
6
7 import java.lang.reflect.Method;
8
9 import mockit.internal.expectations.invocation.MissingInvocation;
10 import mockit.internal.expectations.invocation.UnexpectedInvocation;
11
12 import org.junit.Ignore;
13 import org.junit.Rule;
14 import org.junit.Test;
15 import org.junit.rules.ExpectedException;
16
17
18
19
20 @SuppressWarnings({ "unused", "ParameterHidesMemberVariable" })
21 public final class ExpectationsTest {
22
23
24 @Rule
25 public final ExpectedException thrown = ExpectedException.none();
26
27
28
29
30 @Deprecated
31 public static class Dependency {
32
33
34 @Deprecated
35 int value;
36
37
38
39
40 @Deprecated
41 public Dependency() {
42 value = -1;
43 }
44
45
46
47
48
49
50
51 @Ignore("test")
52 public void setSomething(@Deprecated int value) {
53 }
54
55
56
57
58
59
60
61 public void setSomethingElse(String value) {
62 }
63
64
65
66
67
68
69
70
71
72
73
74 public int doSomething(Integer i, boolean b) {
75 return i;
76 }
77
78
79
80
81
82
83 public int editABunchMoreStuff() {
84 return 1;
85 }
86
87
88
89
90
91
92 public boolean notifyBeforeSave() {
93 return true;
94 }
95
96
97
98
99 public void prepare() {
100 }
101
102
103
104
105 public void save() {
106 }
107
108
109
110
111
112
113
114
115
116
117
118 static int staticMethod(Object o, Exception e) {
119 return -1;
120 }
121 }
122
123
124 @Mocked
125 Dependency mock;
126
127
128
129
130 void exerciseCodeUnderTest() {
131 mock.prepare();
132 mock.setSomething(123);
133 mock.setSomethingElse("anotherValue");
134 mock.setSomething(45);
135 mock.editABunchMoreStuff();
136 mock.notifyBeforeSave();
137 mock.save();
138 }
139
140
141
142
143 @Test
144 public void recordSimpleInvocations() {
145 new Expectations() {
146 {
147 mock.prepare();
148 mock.editABunchMoreStuff();
149 mock.setSomething(45);
150 }
151 };
152
153 exerciseCodeUnderTest();
154 }
155
156
157
158
159 @Test
160 public void recordInvocationThatWillNotOccur() {
161 new Expectations() {
162 {
163 mock.editABunchMoreStuff();
164 result = 123;
165 times = 0;
166 }
167 };
168
169 mock.setSomething(123);
170 mock.prepare();
171 }
172
173
174
175
176 @Test
177 public void expectationsRecordedOnSameMethodWithSameMatchersButDifferentArguments() {
178 new Expectations() {
179 {
180 mock.doSomething(1, anyBoolean);
181 result = 1;
182 mock.doSomething(2, anyBoolean);
183 result = 2;
184 }
185 };
186
187 assertEquals(1, mock.doSomething(1, true));
188 assertEquals(2, mock.doSomething(2, false));
189 assertEquals(0, mock.doSomething(3, false));
190 }
191
192
193
194
195 @Test
196 public void expectationsRecordedOnSameMethodWithMatcherInOneAndFixedArgumentInAnother() {
197 new Expectations() {
198 {
199 mock.doSomething(1, anyBoolean);
200 result = 1;
201 mock.doSomething(anyInt, anyBoolean);
202 result = 2;
203 }
204 };
205
206 assertEquals(1, mock.doSomething(1, true));
207 assertEquals(2, mock.doSomething(null, false));
208 assertEquals(2, mock.doSomething(2, true));
209 assertEquals(1, mock.doSomething(1, false));
210 }
211
212
213
214
215 @Test(expected = MissingInvocation.class)
216 public void recordInvocationWithExactExpectedNumberOfInvocationsButFailToSatisfy() {
217 new Expectations() {
218 {
219 mock.editABunchMoreStuff();
220 times = 1;
221 }
222 };
223 }
224
225
226
227
228 @Test(expected = MissingInvocation.class)
229 public void recordInvocationWithMinimumExpectedNumberOfInvocationsButFailToSatisfy() {
230 new Expectations() {
231 {
232 mock.editABunchMoreStuff();
233 minTimes = 2;
234 }
235 };
236
237 mock.editABunchMoreStuff();
238 }
239
240
241
242
243 @Test(expected = UnexpectedInvocation.class)
244 public void recordInvocationWithMaximumExpectedNumberOfInvocationsButFailToSatisfy() {
245 new Expectations() {
246 {
247 mock.editABunchMoreStuff();
248 maxTimes = 1;
249 }
250 };
251
252 mock.editABunchMoreStuff();
253 mock.editABunchMoreStuff();
254 }
255
256
257
258
259 @Test
260 public void recordInvocationsWithExpectedInvocationCounts() {
261 new Expectations() {
262 {
263 mock.setSomethingElse(anyString);
264 minTimes = 1;
265 mock.save();
266 times = 2;
267 }
268 };
269
270 mock.setSomething(3);
271 mock.save();
272 mock.setSomethingElse("test");
273 mock.save();
274 }
275
276
277
278
279 @Test(expected = MissingInvocation.class)
280 public void recordInvocationsWithMinInvocationCountLargerThanWillOccur() {
281 new Expectations() {
282 {
283 mock.save();
284 minTimes = 2;
285 }
286 };
287
288 mock.save();
289 }
290
291
292
293
294 @Test
295 public void recordWithArgumentMatcherAndIndividualInvocationCounts() {
296 new Expectations() {
297 {
298 mock.prepare();
299 maxTimes = 1;
300 mock.setSomething(anyInt);
301 minTimes = 2;
302 mock.editABunchMoreStuff();
303 maxTimes = 5;
304 mock.save();
305 times = 1;
306 }
307 };
308
309 exerciseCodeUnderTest();
310 }
311
312
313
314
315 @Test
316 public void recordWithMaxInvocationCountFollowedByReturnValue() {
317 new Expectations() {
318 {
319 Dependency.staticMethod(any, null);
320 maxTimes = 1;
321 result = 1;
322 }
323 };
324
325 assertEquals(1, Dependency.staticMethod(new Object(), new Exception()));
326 }
327
328
329
330
331 @Test(expected = UnexpectedInvocation.class)
332 public void recordWithMaxInvocationCountFollowedByReturnValueButReplayOneTimeBeyondMax() {
333 new Expectations() {
334 {
335 Dependency.staticMethod(any, null);
336 maxTimes = 1;
337 result = 1;
338 }
339 };
340
341 Dependency.staticMethod(null, null);
342 Dependency.staticMethod(null, null);
343 }
344
345
346
347
348 @Test
349 public void recordWithReturnValueFollowedByExpectedInvocationCount() {
350 new Expectations() {
351 {
352 Dependency.staticMethod(any, null);
353 result = 1;
354 times = 1;
355 }
356 };
357
358 assertEquals(1, Dependency.staticMethod(null, null));
359 }
360
361
362
363
364 @Test
365 public void recordWithMinInvocationCountFollowedByReturnValueUsingDelegate() {
366 new Expectations() {
367 {
368 Dependency.staticMethod(any, null);
369 minTimes = 1;
370 result = new Delegate<Object>() {
371 int staticMethod(Object o, Exception e) {
372 return 1;
373 }
374 };
375 }
376 };
377
378 assertEquals(1, Dependency.staticMethod(null, null));
379 }
380
381
382
383
384
385
386
387 @Test
388 public void mockedClassWithAnnotatedElements() throws Exception {
389 Class<?> mockedClass = mock.getClass();
390 assertTrue(mockedClass.isAnnotationPresent(Deprecated.class));
391 assertTrue(mockedClass.getDeclaredField("value").isAnnotationPresent(Deprecated.class));
392 assertTrue(mockedClass.getDeclaredConstructor().isAnnotationPresent(Deprecated.class));
393
394 Method mockedMethod = mockedClass.getDeclaredMethod("setSomething", int.class);
395 Ignore ignore = mockedMethod.getAnnotation(Ignore.class);
396 assertNotNull(ignore);
397 assertEquals("test", ignore.value());
398 assertTrue(mockedMethod.getParameterAnnotations()[0][0] instanceof Deprecated);
399 }
400
401
402
403
404 static class Collaborator {
405
406
407 private int value;
408
409
410
411
412
413
414 int getValue() {
415 return value;
416 }
417
418
419
420
421
422
423
424 void setValue(int value) {
425 this.value = value;
426 }
427
428
429
430
431 void provideSomeService() {
432 }
433
434
435
436
437
438
439
440
441
442 String doSomething(String s) {
443 return s.toLowerCase();
444 }
445
446
447
448
449
450
451 static String doInternal() {
452 return "123";
453 }
454 }
455
456
457
458
459
460
461
462 @Test
463 public void expectOnlyOneInvocationButExerciseOthersDuringReplay(@Mocked final Collaborator mock) {
464 thrown.expect(UnexpectedInvocation.class);
465 new Expectations() {
466 {
467 mock.provideSomeService();
468 }
469 };
470
471 mock.provideSomeService();
472 mock.setValue(1);
473
474 new FullVerifications() {
475 };
476 }
477
478
479
480
481
482
483
484 @Test
485 public void expectNothingOnMockedTypeButExerciseItDuringReplay(@Mocked final Collaborator mock) {
486 thrown.expect(UnexpectedInvocation.class);
487 new Expectations() {
488 {
489 mock.setValue(anyInt);
490 times = 0;
491 }
492 };
493
494 mock.setValue(2);
495
496 new FullVerifications() {
497 };
498 }
499
500
501
502
503
504
505
506 @Test
507 public void replayWithUnexpectedStaticMethodInvocation(@Mocked final Collaborator mock) {
508 thrown.expect(UnexpectedInvocation.class);
509 new Expectations() {
510 {
511 mock.getValue();
512 }
513 };
514
515 Collaborator.doInternal();
516
517 new FullVerifications() {
518 };
519 }
520
521
522
523
524
525
526
527
528
529
530 @Test
531 public void failureFromUnexpectedInvocationInAnotherThread(@Mocked final Collaborator mock) throws Exception {
532 Thread t = new Thread() {
533 @Override
534 public void run() {
535 mock.provideSomeService();
536 }
537 };
538
539 new Expectations() {
540 {
541 mock.getValue();
542 }
543 };
544 thrown.expect(UnexpectedInvocation.class);
545
546 mock.getValue();
547 t.start();
548 t.join();
549
550 new FullVerifications() {
551 };
552 }
553
554
555
556
557
558
559
560 @Test
561 public void recordingExpectationOnMethodWithOneArgumentButReplayingWithAnotherShouldProduceUsefulErrorMessage(
562 @Mocked final Collaborator mock) {
563 final String expected = "expected";
564 new Expectations() {
565 {
566 mock.doSomething(expected);
567 }
568 };
569
570 mock.doSomething(expected);
571
572 String another = "another";
573 mock.doSomething(another);
574
575 thrown.expect(UnexpectedInvocation.class);
576 thrown.expectMessage(another);
577 new FullVerifications() {
578 };
579 }
580 }