1 package mockit;
2
3 import static java.util.Arrays.asList;
4 import static java.util.Collections.singletonList;
5
6 import static mockit.ExpectationsWithArgMatchersTest.Delegates.collectionElement;
7 import static org.hamcrest.CoreMatchers.equalTo;
8 import static org.hamcrest.CoreMatchers.hasItem;
9 import static org.hamcrest.Matchers.containsInAnyOrder;
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertFalse;
12 import static org.junit.jupiter.api.Assertions.assertNull;
13 import static org.junit.jupiter.api.Assertions.assertSame;
14 import static org.junit.jupiter.api.Assertions.assertTrue;
15
16 import java.security.cert.Certificate;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Date;
20 import java.util.List;
21
22 import mockit.internal.expectations.invocation.MissingInvocation;
23
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.junit.rules.ExpectedException;
27
28
29
30
31 public final class ExpectationsWithArgMatchersTest {
32
33
34 @Rule
35 public final ExpectedException thrown = ExpectedException.none();
36
37
38
39
40 @SuppressWarnings("unused")
41 static class Collaborator {
42
43
44
45
46
47
48
49 void setValue(int value) {
50 }
51
52
53
54
55
56
57
58 void setValue(double value) {
59 }
60
61
62
63
64
65
66
67
68
69 boolean setValue(float value) {
70 return false;
71 }
72
73
74
75
76
77
78
79 void setValue(char value) {
80 }
81
82
83
84
85
86
87
88 void setValue(String value) {
89 }
90
91
92
93
94
95
96
97
98
99 void setValues(char c, boolean b) {
100 }
101
102
103
104
105
106
107
108 void setValues(String[] values) {
109 }
110
111
112
113
114
115
116
117 void setTextualValues(Collection<String> values) {
118 }
119
120
121
122
123
124
125
126 void doSomething(Integer i) {
127 }
128
129
130
131
132
133
134
135
136
137 boolean doSomething(String s) {
138 return false;
139 }
140
141
142
143
144
145
146
147
148
149
150
151 final void simpleOperation(int a, String b, Date c) {
152 }
153
154
155
156
157
158
159
160 void setValue(Certificate cert) {
161 }
162
163
164
165
166
167
168
169 void setValue(Exception ex) {
170 }
171
172 void setIntValue(int i) {
173 }
174
175
176
177
178
179
180
181
182
183 String useObject(Object arg) {
184 return "";
185 }
186 }
187
188
189 @Mocked
190 Collaborator mock;
191
192
193
194
195 @Test
196 public void verifyExpectationNumericEqualityMatcherButFailToMatchOnReplay() {
197 thrown.expect(MissingInvocation.class);
198 thrown.expectMessage("setValue");
199 thrown.expectMessage("a numeric value within 0.01 of 2.3");
200 thrown.expectMessage("instead got");
201 thrown.expectMessage("setValue(2.32)");
202
203 mock.setValue(2.32);
204
205 new Verifications() {
206 {
207 mock.setValue(withEqual(2.3, 0.01));
208 }
209 };
210 }
211
212
213
214
215 @Test
216 public void verifyExpectationUsingNumericEqualityMatcherButReplayWithNonNumericParameterType() {
217 thrown.expect(MissingInvocation.class);
218
219 mock.useObject('2');
220
221 new Verifications() {
222 {
223 mock.useObject(withEqual(2.3, 0.01));
224 }
225 };
226 }
227
228
229
230
231 @Test
232 public void verifyExpectationUsingInequalityMatcherButFailToMatchOnReplay() {
233 thrown.expect(MissingInvocation.class);
234 thrown.expectMessage("(not 2)");
235 thrown.expectMessage("got");
236 thrown.expectMessage("(2)");
237
238 mock.setValue(2);
239
240 new Verifications() {
241 {
242 mock.setValue(withNotEqual(2));
243 }
244 };
245 }
246
247
248
249
250 @Test
251 public void verifyExpectationsUsingNumericEqualityMatchers() {
252 new Expectations() {
253 {
254 mock.setValue(withEqual(2.0F, 0.01F));
255 result = true;
256 mock.setValue(withEqual(2.0F, 0.05F));
257 result = false;
258 }
259 };
260
261 assertFalse(mock.setValue(2.0F));
262 assertFalse(mock.setValue(2.05F));
263 }
264
265
266
267
268 @Test
269 public void recordExpectationWithDelegateWithoutTheParameterType() {
270 new Expectations() {
271 {
272 mock.useObject(with(new Delegate() {
273 @SuppressWarnings("unused")
274 boolean delegate(Object arg) {
275 return "test".equals(arg);
276 }
277 }));
278 }
279 };
280
281 String result = mock.useObject("test");
282
283 assertNull(result);
284 }
285
286
287
288
289
290
291
292 static final class CollectionElementDelegate<T> implements Delegate<Collection<T>> {
293
294
295 private final T item;
296
297
298
299
300
301
302
303 CollectionElementDelegate(T item) {
304 this.item = item;
305 }
306
307
308
309
310
311
312
313
314
315 @SuppressWarnings("unused")
316 boolean hasItem(Collection<T> items) {
317 return items.contains(item);
318 }
319 }
320
321
322
323
324 @SuppressWarnings("unused")
325 static final class Delegates {
326
327
328
329
330
331
332
333
334
335
336
337 static <T> Delegate<Collection<T>> collectionElement(T item) {
338 return new CollectionElementDelegate<>(item);
339 }
340 }
341
342
343
344
345 @Test
346 public void expectInvocationsWithNamedDelegateMatcher() {
347 new Expectations() {
348 {
349 mock.setTextualValues(with(collectionElement("B")));
350 }
351 };
352
353 List<String> values = asList("a", "B", "c");
354 mock.setTextualValues(values);
355 }
356
357 @Test
358 public void expectInvocationsWithHamcrestMatcher() {
359 new Expectations() {
360 {
361 mock.setTextualValues(this.<Collection<String>> withArgThat(hasItem("B")));
362 }
363 };
364
365 List<String> values = asList("a", "B", "c");
366 mock.setTextualValues(values);
367 }
368
369 @Test
370 public void expectInvocationsWithHamcrestMatcher2() {
371 new Expectations() {
372 {
373 mock.setTextualValues(withArgThat(containsInAnyOrder("B", "c", "a")));
374 }
375 };
376
377 List<String> values = asList("a", "B", "c");
378 mock.setTextualValues(values);
379 }
380
381 @Test
382 public void expectInvocationWithMatcherContainingAnotherMatcher() {
383 new Expectations() {
384 {
385 mock.setIntValue(withArgThat(equalTo(3)));
386 }
387 };
388
389 mock.setIntValue(3);
390 }
391
392
393
394
395 @Test
396 public void useMockedMethodBeforeRecordingExpectationWithArgumentMatcher() {
397 assertFalse(mock.doSomething("abc"));
398
399 new Expectations() {
400 {
401 mock.doSomething(anyString);
402 result = true;
403 }
404 };
405
406 assertTrue(mock.doSomething("xyz"));
407 assertTrue(mock.doSomething("abc"));
408 }
409
410
411
412
413 @Test
414 public void recordExpectationsUsingTheAnyFieldsForParameterOfTypeObject() {
415 new Expectations() {
416 {
417 mock.useObject(anyString);
418 result = "String";
419 mock.useObject(anyInt);
420 result = "int";
421 mock.useObject(anyByte);
422 result = "byte";
423 mock.useObject(anyShort);
424 result = "short";
425 mock.useObject(anyLong);
426 result = "long";
427 mock.useObject(anyBoolean);
428 result = "boolean";
429 mock.useObject(anyChar);
430 result = "char";
431 mock.useObject(anyFloat);
432 result = "float";
433 mock.useObject(anyDouble);
434 result = "double";
435 mock.useObject(any);
436 result = "Object";
437 }
438 };
439
440 assertInvocationsWithArgumentsOfDifferentTypesToMethodAcceptingAnyObject();
441 }
442
443
444
445
446 void assertInvocationsWithArgumentsOfDifferentTypesToMethodAcceptingAnyObject() {
447 assertEquals("String", mock.useObject("test"));
448 assertEquals("String", mock.useObject(null));
449 assertEquals("int", mock.useObject(2));
450 assertEquals("Object", mock.useObject(new Object()));
451 assertEquals("byte", mock.useObject((byte) -3));
452 assertEquals("short", mock.useObject((short) 4));
453 assertEquals("long", mock.useObject(-5L));
454 assertEquals("boolean", mock.useObject(true));
455 assertEquals("boolean", mock.useObject(false));
456 assertEquals("char", mock.useObject('A'));
457 assertEquals("float", mock.useObject(-1.5F));
458 assertEquals("double", mock.useObject(23.456));
459 }
460
461
462
463
464 @Test
465 public void recordExpectationsUsingTheWithAnyMethodForParameterOfTypeObject() {
466 new Expectations() {
467 {
468 mock.useObject(withAny("a"));
469 result = "String";
470 mock.useObject(withAny(2));
471 result = "int";
472 mock.useObject(withAny((byte) 3));
473 result = "byte";
474 mock.useObject(withAny((short) 4));
475 result = "short";
476 mock.useObject(withAny(5L));
477 result = "long";
478 mock.useObject(withAny(true));
479 result = "boolean";
480 mock.useObject(withAny('\0'));
481 result = "char";
482 mock.useObject(withAny(0.41F));
483 result = "float";
484 mock.useObject(withAny(0.41));
485 result = "double";
486 mock.useObject(withAny(new Object()));
487 result = "Object";
488 }
489 };
490
491 assertInvocationsWithArgumentsOfDifferentTypesToMethodAcceptingAnyObject();
492 }
493
494
495
496
497 @Test
498 public void declareFieldInExpectationBlockWithNameHavingSamePrefixAsArgumentMatchingField() {
499 new Expectations() {
500 final Integer anyValue = 1;
501
502 {
503 mock.setValue(anyValue);
504 }
505 };
506
507 mock.setValue(1);
508 }
509
510
511
512
513 @Test
514 public void declareMethodInExpectationBlockWithNameHavingSamePrefixAsArgumentMatchingMethod() {
515 final List<Integer> values = new ArrayList<>();
516
517 new Expectations() {
518 {
519 mock.setValues(withEqual('c'), anyBoolean);
520 mock.setValue(withCapture(values));
521 }
522
523 char withEqual(char c) {
524 return c;
525 }
526 };
527
528 mock.setValues('c', true);
529 final Collaborator col = new Collaborator();
530 col.setValue(1);
531
532 assertEquals(singletonList(1), values);
533
534 new Verifications() {
535 {
536 int i;
537 mock.setValue(i = withCapture());
538 assertEquals(1, i);
539
540 List<Collaborator> collaborators = withCapture(new Collaborator());
541 assertSame(col, collaborators.get(0));
542 }
543 };
544 }
545
546
547
548
549
550
551
552
553
554
555 @Test
556 public void expectInvocationWithSameMockInstanceButReplayWithNull(
557
558
559 @Mocked final Certificate cert) {
560 new Expectations() {
561 {
562 mock.setValue(withSameInstance(cert));
563 times = 1;
564 }
565 };
566
567 mock.setValue((Certificate) null);
568
569 thrown.expect(MissingInvocation.class);
570 }
571
572
573
574
575 @Test
576 public void expectInvocationWithMatcherWhichInvokesMockedMethod() {
577 new Expectations() {
578 {
579 mock.setValue(with(new Delegate<Integer>() {
580 @Mock
581 boolean validateAsPositive(int value) {
582
583 mock.simpleOperation(1, "b", null);
584 return value > 0;
585 }
586 }));
587 }
588 };
589
590 mock.setValue(-3);
591
592 thrown.expect(MissingInvocation.class);
593 }
594
595
596
597
598
599
600
601 static class ReusableMatcher implements Delegate<Integer> {
602
603
604
605
606
607
608
609
610
611 @Mock
612 final boolean isPositive(int i) {
613 return i > 0;
614 }
615 }
616
617
618
619
620 @Test
621 public void extendingAReusableArgumentMatcher() {
622 mock.setValue(5);
623 mock.setValue(123);
624
625 new Verifications() {
626 {
627 mock.setValue(with(new ReusableMatcher() {
628 }));
629 times = 2;
630 }
631 };
632 }
633 }