• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 
6 package org.mockito.internal.exceptions;
7 
8 import org.mockito.exceptions.base.MockitoAssertionError;
9 import org.mockito.exceptions.base.MockitoException;
10 import org.mockito.exceptions.misusing.*;
11 import org.mockito.exceptions.verification.*;
12 import org.mockito.internal.debugging.LocationImpl;
13 import org.mockito.internal.exceptions.util.ScenarioPrinter;
14 import org.mockito.internal.junit.ExceptionFactory;
15 import org.mockito.internal.matchers.LocalizedMatcher;
16 import org.mockito.internal.util.MockUtil;
17 import org.mockito.invocation.DescribedInvocation;
18 import org.mockito.invocation.Invocation;
19 import org.mockito.invocation.InvocationOnMock;
20 import org.mockito.invocation.Location;
21 import org.mockito.listeners.InvocationListener;
22 import org.mockito.mock.MockName;
23 import org.mockito.mock.SerializableMode;
24 
25 import java.lang.reflect.Field;
26 import java.lang.reflect.Method;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.List;
30 
31 import static org.mockito.internal.reporting.Pluralizer.pluralize;
32 import static org.mockito.internal.reporting.Pluralizer.were_exactly_x_interactions;
33 import static org.mockito.internal.util.StringUtil.join;
34 
35 /**
36  * Reports verification and misusing errors.
37  * <p>
38  * One of the key points of mocking library is proper verification/exception
39  * messages. All messages in one place makes it easier to tune and amend them.
40  * <p>
41  * Reporter can be injected and therefore is easily testable.
42  * <p>
43  * Generally, exception messages are full of line breaks to make them easy to
44  * read (xunit plugins take only fraction of screen on modern IDEs).
45  */
46 public class Reporter {
47 
Reporter()48     private Reporter() {
49     }
50 
checkedExceptionInvalid(Throwable t)51     public static MockitoException checkedExceptionInvalid(Throwable t) {
52         return new MockitoException(join(
53                 "Checked exception is invalid for this method!",
54                 "Invalid: " + t
55         ));
56     }
57 
cannotStubWithNullThrowable()58     public static MockitoException cannotStubWithNullThrowable() {
59         return new MockitoException(join(
60                 "Cannot stub with null throwable!"
61         ));
62 
63     }
64 
unfinishedStubbing(Location location)65     public static MockitoException unfinishedStubbing(Location location) {
66         return new UnfinishedStubbingException(join(
67                 "Unfinished stubbing detected here:",
68                 location,
69                 "",
70                 "E.g. thenReturn() may be missing.",
71                 "Examples of correct stubbing:",
72                 "    when(mock.isOk()).thenReturn(true);",
73                 "    when(mock.isOk()).thenThrow(exception);",
74                 "    doThrow(exception).when(mock).someVoidMethod();",
75                 "Hints:",
76                 " 1. missing thenReturn()",
77                 " 2. you are trying to stub a final method, which is not supported",
78                 " 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed",
79                 ""
80         ));
81     }
82 
incorrectUseOfApi()83     public static MockitoException incorrectUseOfApi() {
84         return new MockitoException(join(
85                 "Incorrect use of API detected here:",
86                 new LocationImpl(),
87                 "",
88                 "You probably stored a reference to OngoingStubbing returned by when() and called stubbing methods like thenReturn() on this reference more than once.",
89                 "Examples of correct usage:",
90                 "    when(mock.isOk()).thenReturn(true).thenReturn(false).thenThrow(exception);",
91                 "    when(mock.isOk()).thenReturn(true, false).thenThrow(exception);",
92                 ""
93         ));
94     }
95 
missingMethodInvocation()96     public static MockitoException missingMethodInvocation() {
97         return new MissingMethodInvocationException(join(
98                 "when() requires an argument which has to be 'a method call on a mock'.",
99                 "For example:",
100                 "    when(mock.getArticles()).thenReturn(articles);",
101                 "",
102                 "Also, this error might show up because:",
103                 "1. you stub either of: final/private/equals()/hashCode() methods.",
104                 "   Those methods *cannot* be stubbed/verified.",
105                 "   " + MockitoLimitations.NON_PUBLIC_PARENT,
106                 "2. inside when() you don't call method on mock but on some other object.",
107                 ""
108         ));
109     }
110 
unfinishedVerificationException(Location location)111     public static MockitoException unfinishedVerificationException(Location location) {
112         return new UnfinishedVerificationException(join(
113                 "Missing method call for verify(mock) here:",
114                 location,
115                 "",
116                 "Example of correct verification:",
117                 "    verify(mock).doSomething()",
118                 "",
119                 "Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.",
120                 "Those methods *cannot* be stubbed/verified.",
121                 MockitoLimitations.NON_PUBLIC_PARENT,
122                 ""
123         ));
124     }
125 
notAMockPassedToVerify(Class<?> type)126     public static MockitoException notAMockPassedToVerify(Class<?> type) {
127         return new NotAMockException(join(
128                 "Argument passed to verify() is of type " + type.getSimpleName() + " and is not a mock!",
129                 "Make sure you place the parenthesis correctly!",
130                 "See the examples of correct verifications:",
131                 "    verify(mock).someMethod();",
132                 "    verify(mock, times(10)).someMethod();",
133                 "    verify(mock, atLeastOnce()).someMethod();"
134         ));
135     }
136 
nullPassedToVerify()137     public static MockitoException nullPassedToVerify() {
138         return new NullInsteadOfMockException(join(
139                 "Argument passed to verify() should be a mock but is null!",
140                 "Examples of correct verifications:",
141                 "    verify(mock).someMethod();",
142                 "    verify(mock, times(10)).someMethod();",
143                 "    verify(mock, atLeastOnce()).someMethod();",
144                 "    not: verify(mock.someMethod());",
145                 "Also, if you use @Mock annotation don't miss initMocks()"
146         ));
147     }
148 
notAMockPassedToWhenMethod()149     public static MockitoException notAMockPassedToWhenMethod() {
150         return new NotAMockException(join(
151                 "Argument passed to when() is not a mock!",
152                 "Example of correct stubbing:",
153                 "    doThrow(new RuntimeException()).when(mock).someMethod();"
154         ));
155     }
156 
nullPassedToWhenMethod()157     public static MockitoException nullPassedToWhenMethod() {
158         return new NullInsteadOfMockException(join(
159                 "Argument passed to when() is null!",
160                 "Example of correct stubbing:",
161                 "    doThrow(new RuntimeException()).when(mock).someMethod();",
162                 "Also, if you use @Mock annotation don't miss initMocks()"
163         ));
164     }
165 
mocksHaveToBePassedToVerifyNoMoreInteractions()166     public static MockitoException mocksHaveToBePassedToVerifyNoMoreInteractions() {
167         return new MockitoException(join(
168                 "Method requires argument(s)!",
169                 "Pass mocks that should be verified, e.g:",
170                 "    verifyNoMoreInteractions(mockOne, mockTwo);",
171                 "    verifyZeroInteractions(mockOne, mockTwo);",
172                 ""
173         ));
174     }
175 
notAMockPassedToVerifyNoMoreInteractions()176     public static MockitoException notAMockPassedToVerifyNoMoreInteractions() {
177         return new NotAMockException(join(
178                 "Argument(s) passed is not a mock!",
179                 "Examples of correct verifications:",
180                 "    verifyNoMoreInteractions(mockOne, mockTwo);",
181                 "    verifyZeroInteractions(mockOne, mockTwo);",
182                 ""
183         ));
184     }
185 
nullPassedToVerifyNoMoreInteractions()186     public static MockitoException nullPassedToVerifyNoMoreInteractions() {
187         return new NullInsteadOfMockException(join(
188                 "Argument(s) passed is null!",
189                 "Examples of correct verifications:",
190                 "    verifyNoMoreInteractions(mockOne, mockTwo);",
191                 "    verifyZeroInteractions(mockOne, mockTwo);"
192         ));
193     }
194 
notAMockPassedWhenCreatingInOrder()195     public static MockitoException notAMockPassedWhenCreatingInOrder() {
196         return new NotAMockException(join(
197                 "Argument(s) passed is not a mock!",
198                 "Pass mocks that require verification in order.",
199                 "For example:",
200                 "    InOrder inOrder = inOrder(mockOne, mockTwo);"
201         ));
202     }
203 
nullPassedWhenCreatingInOrder()204     public static MockitoException nullPassedWhenCreatingInOrder() {
205         return new NullInsteadOfMockException(join(
206                 "Argument(s) passed is null!",
207                 "Pass mocks that require verification in order.",
208                 "For example:",
209                 "    InOrder inOrder = inOrder(mockOne, mockTwo);"
210         ));
211     }
212 
mocksHaveToBePassedWhenCreatingInOrder()213     public static MockitoException mocksHaveToBePassedWhenCreatingInOrder() {
214         return new MockitoException(join(
215                 "Method requires argument(s)!",
216                 "Pass mocks that require verification in order.",
217                 "For example:",
218                 "    InOrder inOrder = inOrder(mockOne, mockTwo);"
219         ));
220     }
221 
inOrderRequiresFamiliarMock()222     public static MockitoException inOrderRequiresFamiliarMock() {
223         return new MockitoException(join(
224                 "InOrder can only verify mocks that were passed in during creation of InOrder.",
225                 "For example:",
226                 "    InOrder inOrder = inOrder(mockOne);",
227                 "    inOrder.verify(mockOne).doStuff();"
228         ));
229     }
230 
invalidUseOfMatchers(int expectedMatchersCount, List<LocalizedMatcher> recordedMatchers)231     public static MockitoException invalidUseOfMatchers(int expectedMatchersCount, List<LocalizedMatcher> recordedMatchers) {
232         return new InvalidUseOfMatchersException(join(
233                 "Invalid use of argument matchers!",
234                 expectedMatchersCount + " matchers expected, " + recordedMatchers.size() + " recorded:" +
235                         locationsOf(recordedMatchers),
236                 "",
237                 "This exception may occur if matchers are combined with raw values:",
238                 "    //incorrect:",
239                 "    someMethod(anyObject(), \"raw String\");",
240                 "When using matchers, all arguments have to be provided by matchers.",
241                 "For example:",
242                 "    //correct:",
243                 "    someMethod(anyObject(), eq(\"String by matcher\"));",
244                 "",
245                 "For more info see javadoc for Matchers class.",
246                 ""
247         ));
248     }
249 
incorrectUseOfAdditionalMatchers(String additionalMatcherName, int expectedSubMatchersCount, Collection<LocalizedMatcher> matcherStack)250     public static MockitoException incorrectUseOfAdditionalMatchers(String additionalMatcherName, int expectedSubMatchersCount, Collection<LocalizedMatcher> matcherStack) {
251         return new InvalidUseOfMatchersException(join(
252                 "Invalid use of argument matchers inside additional matcher " + additionalMatcherName + " !",
253                 new LocationImpl(),
254                 "",
255                 expectedSubMatchersCount + " sub matchers expected, " + matcherStack.size() + " recorded:",
256                 locationsOf(matcherStack),
257                 "",
258                 "This exception may occur if matchers are combined with raw values:",
259                 "    //incorrect:",
260                 "    someMethod(AdditionalMatchers.and(isNotNull(), \"raw String\");",
261                 "When using matchers, all arguments have to be provided by matchers.",
262                 "For example:",
263                 "    //correct:",
264                 "    someMethod(AdditionalMatchers.and(isNotNull(), eq(\"raw String\"));",
265                 "",
266                 "For more info see javadoc for Matchers and AdditionalMatchers classes.",
267                 ""
268         ));
269     }
270 
stubPassedToVerify()271     public static MockitoException stubPassedToVerify() {
272         return new CannotVerifyStubOnlyMock(join(
273                 "Argument passed to verify() is a stubOnly() mock, not a full blown mock!",
274                 "If you intend to verify invocations on a mock, don't use stubOnly() in its MockSettings."
275         ));
276     }
277 
reportNoSubMatchersFound(String additionalMatcherName)278     public static MockitoException reportNoSubMatchersFound(String additionalMatcherName) {
279         return new InvalidUseOfMatchersException(join(
280                 "No matchers found for additional matcher " + additionalMatcherName,
281                 new LocationImpl(),
282                 ""
283         ));
284     }
285 
286 
locationsOf(Collection<LocalizedMatcher> matchers)287     private static Object locationsOf(Collection<LocalizedMatcher> matchers) {
288         List<String> description = new ArrayList<String>();
289         for (LocalizedMatcher matcher : matchers)
290             description.add(matcher.getLocation().toString());
291         return join(description.toArray());
292     }
293 
argumentsAreDifferent(String wanted, String actual, Location actualLocation)294     public static AssertionError argumentsAreDifferent(String wanted, String actual, Location actualLocation) {
295         String message = join("Argument(s) are different! Wanted:",
296                               wanted,
297                               new LocationImpl(),
298                               "Actual invocation has different arguments:",
299                               actual,
300                               actualLocation,
301                               ""
302         );
303 
304         return ExceptionFactory.createArgumentsAreDifferentException(message, wanted, actual);
305     }
306 
wantedButNotInvoked(DescribedInvocation wanted)307     public static MockitoAssertionError wantedButNotInvoked(DescribedInvocation wanted) {
308         return new WantedButNotInvoked(createWantedButNotInvokedMessage(wanted));
309     }
310 
wantedButNotInvoked(DescribedInvocation wanted, List<? extends DescribedInvocation> invocations)311     public static MockitoAssertionError wantedButNotInvoked(DescribedInvocation wanted, List<? extends DescribedInvocation> invocations) {
312         String allInvocations;
313         if (invocations.isEmpty()) {
314             allInvocations = "Actually, there were zero interactions with this mock.\n";
315         } else {
316             StringBuilder sb = new StringBuilder(
317                     "\nHowever, there " + were_exactly_x_interactions(invocations.size()) + " with this mock:\n");
318             for (DescribedInvocation i : invocations) {
319                 sb.append(i.toString())
320                   .append("\n")
321                   .append(i.getLocation())
322                   .append("\n\n");
323             }
324             allInvocations = sb.toString();
325         }
326 
327         String message = createWantedButNotInvokedMessage(wanted);
328         return new WantedButNotInvoked(message + allInvocations);
329     }
330 
createWantedButNotInvokedMessage(DescribedInvocation wanted)331     private static String createWantedButNotInvokedMessage(DescribedInvocation wanted) {
332         return join(
333                 "Wanted but not invoked:",
334                 wanted.toString(),
335                 new LocationImpl(),
336                 ""
337         );
338     }
339 
wantedButNotInvokedInOrder(DescribedInvocation wanted, DescribedInvocation previous)340     public static MockitoAssertionError wantedButNotInvokedInOrder(DescribedInvocation wanted, DescribedInvocation previous) {
341         return new VerificationInOrderFailure(join(
342                 "Verification in order failure",
343                 "Wanted but not invoked:",
344                 wanted.toString(),
345                 new LocationImpl(),
346                 "Wanted anywhere AFTER following interaction:",
347                 previous.toString(),
348                 previous.getLocation(),
349                 ""
350         ));
351     }
352 
tooManyActualInvocations(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired)353     public static MockitoAssertionError tooManyActualInvocations(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired) {
354         String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, firstUndesired);
355         return new TooManyActualInvocations(message);
356     }
357 
createTooManyInvocationsMessage(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired)358     private static String createTooManyInvocationsMessage(int wantedCount, int actualCount, DescribedInvocation wanted,
359                                                           Location firstUndesired) {
360         return join(
361                 wanted.toString(),
362                 "Wanted " + pluralize(wantedCount) + ":",
363                 new LocationImpl(),
364                 "But was " + pluralize(actualCount) + ". Undesired invocation:",
365                 firstUndesired,
366                 ""
367         );
368     }
369 
neverWantedButInvoked(DescribedInvocation wanted, Location firstUndesired)370     public static MockitoAssertionError neverWantedButInvoked(DescribedInvocation wanted, Location firstUndesired) {
371         return new NeverWantedButInvoked(join(
372                 wanted.toString(),
373                 "Never wanted here:",
374                 new LocationImpl(),
375                 "But invoked here:",
376                 firstUndesired,
377                 ""
378         ));
379     }
380 
tooManyActualInvocationsInOrder(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired)381     public static MockitoAssertionError tooManyActualInvocationsInOrder(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired) {
382         String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, firstUndesired);
383         return new VerificationInOrderFailure(join(
384                 "Verification in order failure:" + message
385         ));
386     }
387 
createTooLittleInvocationsMessage(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualInvocation)388     private static String createTooLittleInvocationsMessage(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted,
389                                                             Location lastActualInvocation) {
390         String ending =
391                 (lastActualInvocation != null) ? lastActualInvocation + "\n" : "\n";
392 
393         return join(
394                 wanted.toString(),
395                 "Wanted " + discrepancy.getPluralizedWantedCount() + (discrepancy.getWantedCount() == 0 ? "." : ":"),
396                 new LocationImpl(),
397                 "But was " + discrepancy.getPluralizedActualCount() + (discrepancy.getActualCount() == 0 ? "." : ":"),
398                 ending
399         );
400     }
401 
tooLittleActualInvocations(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation)402     public static MockitoAssertionError tooLittleActualInvocations(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation) {
403         String message = createTooLittleInvocationsMessage(discrepancy, wanted, lastActualLocation);
404 
405         return new TooLittleActualInvocations(message);
406     }
407 
tooLittleActualInvocationsInOrder(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation)408     public static MockitoAssertionError tooLittleActualInvocationsInOrder(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation) {
409         String message = createTooLittleInvocationsMessage(discrepancy, wanted, lastActualLocation);
410 
411         return new VerificationInOrderFailure(join(
412                 "Verification in order failure:" + message
413         ));
414     }
415 
noMoreInteractionsWanted(Invocation undesired, List<VerificationAwareInvocation> invocations)416     public static MockitoAssertionError noMoreInteractionsWanted(Invocation undesired, List<VerificationAwareInvocation> invocations) {
417         ScenarioPrinter scenarioPrinter = new ScenarioPrinter();
418         String scenario = scenarioPrinter.print(invocations);
419 
420         return new NoInteractionsWanted(join(
421                 "No interactions wanted here:",
422                 new LocationImpl(),
423                 "But found this interaction on mock '" + safelyGetMockName(undesired.getMock()) + "':",
424                 undesired.getLocation(),
425                 scenario
426         ));
427     }
428 
noMoreInteractionsWantedInOrder(Invocation undesired)429     public static MockitoAssertionError noMoreInteractionsWantedInOrder(Invocation undesired) {
430         return new VerificationInOrderFailure(join(
431                 "No interactions wanted here:",
432                 new LocationImpl(),
433                 "But found this interaction on mock '" + safelyGetMockName(undesired.getMock()) + "':",
434                 undesired.getLocation()
435         ));
436     }
437 
cannotMockClass(Class<?> clazz, String reason)438     public static MockitoException cannotMockClass(Class<?> clazz, String reason) {
439         return new MockitoException(join(
440                 "Cannot mock/spy " + clazz.toString(),
441                 "Mockito cannot mock/spy because :",
442                 " - " + reason
443         ));
444     }
445 
cannotStubVoidMethodWithAReturnValue(String methodName)446     public static MockitoException cannotStubVoidMethodWithAReturnValue(String methodName) {
447         return new CannotStubVoidMethodWithReturnValue(join(
448                 "'" + methodName + "' is a *void method* and it *cannot* be stubbed with a *return value*!",
449                 "Voids are usually stubbed with Throwables:",
450                 "    doThrow(exception).when(mock).someVoidMethod();",
451                 "***",
452                 "If you're unsure why you're getting above error read on.",
453                 "Due to the nature of the syntax above problem might occur because:",
454                 "1. The method you are trying to stub is *overloaded*. Make sure you are calling the right overloaded version.",
455                 "2. Somewhere in your test you are stubbing *final methods*. Sorry, Mockito does not verify/stub final methods.",
456                 "3. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - ",
457                 "   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.",
458                 "4. " + MockitoLimitations.NON_PUBLIC_PARENT,
459                 ""
460         ));
461     }
462 
onlyVoidMethodsCanBeSetToDoNothing()463     public static MockitoException onlyVoidMethodsCanBeSetToDoNothing() {
464         return new MockitoException(join(
465                 "Only void methods can doNothing()!",
466                 "Example of correct use of doNothing():",
467                 "    doNothing().",
468                 "    doThrow(new RuntimeException())",
469                 "    .when(mock).someVoidMethod();",
470                 "Above means:",
471                 "someVoidMethod() does nothing the 1st time but throws an exception the 2nd time is called"
472         ));
473     }
474 
wrongTypeOfReturnValue(String expectedType, String actualType, String methodName)475     public static MockitoException wrongTypeOfReturnValue(String expectedType, String actualType, String methodName) {
476         return new WrongTypeOfReturnValue(join(
477                 actualType + " cannot be returned by " + methodName + "()",
478                 methodName + "() should return " + expectedType,
479                 "***",
480                 "If you're unsure why you're getting above error read on.",
481                 "Due to the nature of the syntax above problem might occur because:",
482                 "1. This exception *might* occur in wrongly written multi-threaded tests.",
483                 "   Please refer to Mockito FAQ on limitations of concurrency testing.",
484                 "2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - ",
485                 "   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.",
486                 ""
487         ));
488     }
489 
wrongTypeReturnedByDefaultAnswer(Object mock, String expectedType, String actualType, String methodName)490     public static MockitoException wrongTypeReturnedByDefaultAnswer(Object mock, String expectedType, String actualType, String methodName) {
491         return new WrongTypeOfReturnValue(join(
492                 "Default answer returned a result with the wrong type:",
493                 actualType + " cannot be returned by " + methodName + "()",
494                 methodName + "() should return " + expectedType,
495                 "",
496                 "The default answer of " + safelyGetMockName(mock) + " that was configured on the mock is probably incorrectly implemented.",
497                 ""
498         ));
499     }
500 
501 
wantedAtMostX(int maxNumberOfInvocations, int foundSize)502     public static MockitoAssertionError wantedAtMostX(int maxNumberOfInvocations, int foundSize) {
503         return new MockitoAssertionError(join("Wanted at most " + pluralize(maxNumberOfInvocations) + " but was " + foundSize));
504     }
505 
misplacedArgumentMatcher(List<LocalizedMatcher> lastMatchers)506     public static MockitoException misplacedArgumentMatcher(List<LocalizedMatcher> lastMatchers) {
507         return new InvalidUseOfMatchersException(join(
508                 "Misplaced or misused argument matcher detected here:",
509                 locationsOf(lastMatchers),
510                 "",
511                 "You cannot use argument matchers outside of verification or stubbing.",
512                 "Examples of correct usage of argument matchers:",
513                 "    when(mock.get(anyInt())).thenReturn(null);",
514                 "    doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());",
515                 "    verify(mock).someMethod(contains(\"foo\"))",
516                 "",
517                 "This message may appear after an NullPointerException if the last matcher is returning an object ",
518                 "like any() but the stubbed method signature expect a primitive argument, in this case,",
519                 "use primitive alternatives.",
520                 "    when(mock.get(any())); // bad use, will raise NPE",
521                 "    when(mock.get(anyInt())); // correct usage use",
522                 "",
523                 "Also, this error might show up because you use argument matchers with methods that cannot be mocked.",
524                 "Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().",
525                 MockitoLimitations.NON_PUBLIC_PARENT,
526                 ""
527         ));
528     }
529 
smartNullPointerException(String invocation, Location location)530     public static MockitoException smartNullPointerException(String invocation, Location location) {
531         return new SmartNullPointerException(join(
532                 "You have a NullPointerException here:",
533                 new LocationImpl(),
534                 "because this method call was *not* stubbed correctly:",
535                 location,
536                 invocation,
537                 ""
538         ));
539     }
540 
noArgumentValueWasCaptured()541     public static MockitoException noArgumentValueWasCaptured() {
542         return new MockitoException(join(
543                 "No argument value was captured!",
544                 "You might have forgotten to use argument.capture() in verify()...",
545                 "...or you used capture() in stubbing but stubbed method was not called.",
546                 "Be aware that it is recommended to use capture() only with verify()",
547                 "",
548                 "Examples of correct argument capturing:",
549                 "    ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);",
550                 "    verify(mock).doSomething(argument.capture());",
551                 "    assertEquals(\"John\", argument.getValue().getName());",
552                 ""
553         ));
554     }
555 
extraInterfacesDoesNotAcceptNullParameters()556     public static MockitoException extraInterfacesDoesNotAcceptNullParameters() {
557         return new MockitoException(join(
558                 "extraInterfaces() does not accept null parameters."
559         ));
560     }
561 
extraInterfacesAcceptsOnlyInterfaces(Class<?> wrongType)562     public static MockitoException extraInterfacesAcceptsOnlyInterfaces(Class<?> wrongType) {
563         return new MockitoException(join(
564                 "extraInterfaces() accepts only interfaces.",
565                 "You passed following type: " + wrongType.getSimpleName() + " which is not an interface."
566         ));
567     }
568 
extraInterfacesCannotContainMockedType(Class<?> wrongType)569     public static MockitoException extraInterfacesCannotContainMockedType(Class<?> wrongType) {
570         return new MockitoException(join(
571                 "extraInterfaces() does not accept the same type as the mocked type.",
572                 "You mocked following type: " + wrongType.getSimpleName(),
573                 "and you passed the same very interface to the extraInterfaces()"
574         ));
575     }
576 
extraInterfacesRequiresAtLeastOneInterface()577     public static MockitoException extraInterfacesRequiresAtLeastOneInterface() {
578         return new MockitoException(join(
579                 "extraInterfaces() requires at least one interface."
580         ));
581     }
582 
mockedTypeIsInconsistentWithSpiedInstanceType(Class<?> mockedType, Object spiedInstance)583     public static MockitoException mockedTypeIsInconsistentWithSpiedInstanceType(Class<?> mockedType, Object spiedInstance) {
584         return new MockitoException(join(
585                 "Mocked type must be the same as the type of your spied instance.",
586                 "Mocked type must be: " + spiedInstance.getClass().getSimpleName() + ", but is: " + mockedType.getSimpleName(),
587                 "  //correct spying:",
588                 "  spy = mock( ->ArrayList.class<- , withSettings().spiedInstance( ->new ArrayList()<- );",
589                 "  //incorrect - types don't match:",
590                 "  spy = mock( ->List.class<- , withSettings().spiedInstance( ->new ArrayList()<- );"
591         ));
592     }
593 
cannotCallAbstractRealMethod()594     public static MockitoException cannotCallAbstractRealMethod() {
595         return new MockitoException(join(
596                 "Cannot call abstract real method on java object!",
597                 "Calling real methods is only possible when mocking non abstract method.",
598                 "  //correct example:",
599                 "  when(mockOfConcreteClass.nonAbstractMethod()).thenCallRealMethod();"
600         ));
601     }
602 
cannotVerifyToString()603     public static MockitoException cannotVerifyToString() {
604         return new MockitoException(join(
605                 "Mockito cannot verify toString()",
606                 "toString() is too often used behind of scenes  (i.e. during String concatenation, in IDE debugging views). " +
607                         "Verifying it may give inconsistent or hard to understand results. " +
608                         "Not to mention that verifying toString() most likely hints awkward design (hard to explain in a short exception message. Trust me...)",
609                 "However, it is possible to stub toString(). Stubbing toString() smells a bit funny but there are rare, legitimate use cases."
610         ));
611     }
612 
moreThanOneAnnotationNotAllowed(String fieldName)613     public static MockitoException moreThanOneAnnotationNotAllowed(String fieldName) {
614         return new MockitoException("You cannot have more than one Mockito annotation on a field!\n" +
615                                             "The field '" + fieldName + "' has multiple Mockito annotations.\n" +
616                                             "For info how to use annotations see examples in javadoc for MockitoAnnotations class.");
617     }
618 
unsupportedCombinationOfAnnotations(String undesiredAnnotationOne, String undesiredAnnotationTwo)619     public static MockitoException unsupportedCombinationOfAnnotations(String undesiredAnnotationOne, String undesiredAnnotationTwo) {
620         return new MockitoException("This combination of annotations is not permitted on a single field:\n" +
621                                             "@" + undesiredAnnotationOne + " and @" + undesiredAnnotationTwo);
622     }
623 
cannotInitializeForSpyAnnotation(String fieldName, Exception details)624     public static MockitoException cannotInitializeForSpyAnnotation(String fieldName, Exception details) {
625         return new MockitoException(join("Cannot instantiate a @Spy for '" + fieldName + "' field.",
626                                          "You haven't provided the instance for spying at field declaration so I tried to construct the instance.",
627                                          "However, I failed because: " + details.getMessage(),
628                                          "Examples of correct usage of @Spy:",
629                                          "   @Spy List mock = new LinkedList();",
630                                          "   @Spy Foo foo; //only if Foo has parameterless constructor",
631                                          "   //also, don't forget about MockitoAnnotations.initMocks();",
632                                          ""), details);
633     }
634 
cannotInitializeForInjectMocksAnnotation(String fieldName, String causeMessage)635     public static MockitoException cannotInitializeForInjectMocksAnnotation(String fieldName, String causeMessage) {
636         return new MockitoException(join("Cannot instantiate @InjectMocks field named '" + fieldName + "'! Cause: "+causeMessage,
637                                          "You haven't provided the instance at field declaration so I tried to construct the instance.",
638                                          "Examples of correct usage of @InjectMocks:",
639                                          "   @InjectMocks Service service = new Service();",
640                                          "   @InjectMocks Service service;",
641                                          "   //and... don't forget about some @Mocks for injection :)",
642                                          ""));
643     }
644 
atMostAndNeverShouldNotBeUsedWithTimeout()645     public static MockitoException atMostAndNeverShouldNotBeUsedWithTimeout() {
646         return new FriendlyReminderException(join("",
647                                                   "Don't panic! I'm just a friendly reminder!",
648                                                   "timeout() should not be used with atMost() or never() because...",
649                                                   "...it does not make much sense - the test would have passed immediately in concurency",
650                                                   "We kept this method only to avoid compilation errors when upgrading Mockito.",
651                                                   "In future release we will remove timeout(x).atMost(y) from the API.",
652                                                   "If you want to find out more please refer to issue 235",
653                                                   ""));
654     }
655 
fieldInitialisationThrewException(Field field, Throwable details)656     public static MockitoException fieldInitialisationThrewException(Field field, Throwable details) {
657         return new MockitoException(join(
658                 "Cannot instantiate @InjectMocks field named '" + field.getName() + "' of type '" + field.getType() + "'.",
659                 "You haven't provided the instance at field declaration so I tried to construct the instance.",
660                 "However the constructor or the initialization block threw an exception : " + details.getMessage(),
661                 ""), details);
662 
663     }
664 
invocationListenerDoesNotAcceptNullParameters()665     public static MockitoException invocationListenerDoesNotAcceptNullParameters() {
666         return new MockitoException("invocationListeners() does not accept null parameters");
667     }
668 
invocationListenersRequiresAtLeastOneListener()669     public static MockitoException invocationListenersRequiresAtLeastOneListener() {
670         return new MockitoException("invocationListeners() requires at least one listener");
671     }
672 
invocationListenerThrewException(InvocationListener listener, Throwable listenerThrowable)673     public static MockitoException invocationListenerThrewException(InvocationListener listener, Throwable listenerThrowable) {
674         return new MockitoException(join(
675                 "The invocation listener with type " + listener.getClass().getName(),
676                 "threw an exception : " + listenerThrowable.getClass().getName() + listenerThrowable.getMessage()), listenerThrowable);
677     }
678 
cannotInjectDependency(Field field, Object matchingMock, Exception details)679     public static MockitoException cannotInjectDependency(Field field, Object matchingMock, Exception details) {
680         return new MockitoException(join(
681                 "Mockito couldn't inject mock dependency '" + safelyGetMockName(matchingMock) + "' on field ",
682                 "'" + field + "'",
683                 "whose type '" + field.getDeclaringClass().getCanonicalName() + "' was annotated by @InjectMocks in your test.",
684                 "Also I failed because: " + exceptionCauseMessageIfAvailable(details),
685                 ""
686         ), details);
687     }
688 
exceptionCauseMessageIfAvailable(Exception details)689     private static String exceptionCauseMessageIfAvailable(Exception details) {
690         if (details.getCause() == null) {
691             return details.getMessage();
692         }
693         return details.getCause().getMessage();
694     }
695 
mockedTypeIsInconsistentWithDelegatedInstanceType(Class<?> mockedType, Object delegatedInstance)696     public static MockitoException mockedTypeIsInconsistentWithDelegatedInstanceType(Class<?> mockedType, Object delegatedInstance) {
697         return new MockitoException(join(
698                 "Mocked type must be the same as the type of your delegated instance.",
699                 "Mocked type must be: " + delegatedInstance.getClass().getSimpleName() + ", but is: " + mockedType.getSimpleName(),
700                 "  //correct delegate:",
701                 "  spy = mock( ->List.class<- , withSettings().delegatedInstance( ->new ArrayList()<- );",
702                 "  //incorrect - types don't match:",
703                 "  spy = mock( ->List.class<- , withSettings().delegatedInstance( ->new HashSet()<- );"
704         ));
705     }
706 
spyAndDelegateAreMutuallyExclusive()707     public static MockitoException spyAndDelegateAreMutuallyExclusive() {
708         return new MockitoException(join(
709                 "Settings should not define a spy instance and a delegated instance at the same time."
710         ));
711     }
712 
invalidArgumentRangeAtIdentityAnswerCreationTime()713     public static MockitoException invalidArgumentRangeAtIdentityAnswerCreationTime() {
714         return new MockitoException(join(
715                 "Invalid argument index.",
716                 "The index need to be a positive number that indicates the position of the argument to return.",
717                 "However it is possible to use the -1 value to indicates that the last argument should be",
718                 "returned."));
719     }
720 
invalidArgumentPositionRangeAtInvocationTime(InvocationOnMock invocation, boolean willReturnLastParameter, int argumentIndex)721     public static MockitoException invalidArgumentPositionRangeAtInvocationTime(InvocationOnMock invocation, boolean willReturnLastParameter, int argumentIndex) {
722         return new MockitoException(join(
723                 "Invalid argument index for the current invocation of method : ",
724                 " -> " + safelyGetMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()",
725                 "",
726                 (willReturnLastParameter ?
727                         "Last parameter wanted" :
728                         "Wanted parameter at position " + argumentIndex) + " but " + possibleArgumentTypesOf(invocation),
729                 "The index need to be a positive number that indicates a valid position of the argument in the invocation.",
730                 "However it is possible to use the -1 value to indicates that the last argument should be returned.",
731                 ""
732         ));
733     }
734 
possibleArgumentTypesOf(InvocationOnMock invocation)735     private static StringBuilder possibleArgumentTypesOf(InvocationOnMock invocation) {
736         Class<?>[] parameterTypes = invocation.getMethod().getParameterTypes();
737         if (parameterTypes.length == 0) {
738             return new StringBuilder("the method has no arguments.\n");
739         }
740 
741         StringBuilder stringBuilder = new StringBuilder("the possible argument indexes for this method are :\n");
742         for (int i = 0, parameterTypesLength = parameterTypes.length; i < parameterTypesLength; i++) {
743             stringBuilder.append("    [").append(i);
744 
745             if (invocation.getMethod().isVarArgs() && i == parameterTypesLength - 1) {
746                 stringBuilder.append("+] ").append(parameterTypes[i].getComponentType().getSimpleName()).append("  <- Vararg").append("\n");
747             } else {
748                 stringBuilder.append("] ").append(parameterTypes[i].getSimpleName()).append("\n");
749             }
750         }
751         return stringBuilder;
752     }
753 
wrongTypeOfArgumentToReturn(InvocationOnMock invocation, String expectedType, Class<?> actualType, int argumentIndex)754     public static MockitoException wrongTypeOfArgumentToReturn(InvocationOnMock invocation, String expectedType, Class<?> actualType, int argumentIndex) {
755         return new WrongTypeOfReturnValue(join(
756                 "The argument of type '" + actualType.getSimpleName() + "' cannot be returned because the following ",
757                 "method should return the type '" + expectedType + "'",
758                 " -> " + safelyGetMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()",
759                 "",
760                 "The reason for this error can be :",
761                 "1. The wanted argument position is incorrect.",
762                 "2. The answer is used on the wrong interaction.",
763                 "",
764                 "Position of the wanted argument is " + argumentIndex + " and " + possibleArgumentTypesOf(invocation),
765                 "***",
766                 "However if you're still unsure why you're getting above error read on.",
767                 "Due to the nature of the syntax above problem might occur because:",
768                 "1. This exception *might* occur in wrongly written multi-threaded tests.",
769                 "   Please refer to Mockito FAQ on limitations of concurrency testing.",
770                 "2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - ",
771                 "   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.",
772                 ""
773         ));
774     }
775 
defaultAnswerDoesNotAcceptNullParameter()776     public static MockitoException defaultAnswerDoesNotAcceptNullParameter() {
777         return new MockitoException("defaultAnswer() does not accept null parameter");
778     }
779 
serializableWontWorkForObjectsThatDontImplementSerializable(Class<?> classToMock)780     public static MockitoException serializableWontWorkForObjectsThatDontImplementSerializable(Class<?> classToMock) {
781         return new MockitoException(join(
782                 "You are using the setting 'withSettings().serializable()' however the type you are trying to mock '" + classToMock.getSimpleName() + "'",
783                 "do not implement Serializable AND do not have a no-arg constructor.",
784                 "This combination is requested, otherwise you will get an 'java.io.InvalidClassException' when the mock will be serialized",
785                 "",
786                 "Also note that as requested by the Java serialization specification, the whole hierarchy need to implements Serializable,",
787                 "i.e. the top-most superclass has to implements Serializable.",
788                 ""
789         ));
790     }
791 
delegatedMethodHasWrongReturnType(Method mockMethod, Method delegateMethod, Object mock, Object delegate)792     public static MockitoException delegatedMethodHasWrongReturnType(Method mockMethod, Method delegateMethod, Object mock, Object delegate) {
793         return new MockitoException(join(
794                 "Methods called on delegated instance must have compatible return types with the mock.",
795                 "When calling: " + mockMethod + " on mock: " + safelyGetMockName(mock),
796                 "return type should be: " + mockMethod.getReturnType().getSimpleName() + ", but was: " + delegateMethod.getReturnType().getSimpleName(),
797                 "Check that the instance passed to delegatesTo() is of the correct type or contains compatible methods",
798                 "(delegate instance had type: " + delegate.getClass().getSimpleName() + ")"
799         ));
800     }
801 
delegatedMethodDoesNotExistOnDelegate(Method mockMethod, Object mock, Object delegate)802     public static MockitoException delegatedMethodDoesNotExistOnDelegate(Method mockMethod, Object mock, Object delegate) {
803         return new MockitoException(join(
804                 "Methods called on mock must exist in delegated instance.",
805                 "When calling: " + mockMethod + " on mock: " + safelyGetMockName(mock),
806                 "no such method was found.",
807                 "Check that the instance passed to delegatesTo() is of the correct type or contains compatible methods",
808                 "(delegate instance had type: " + delegate.getClass().getSimpleName() + ")"
809         ));
810     }
811 
usingConstructorWithFancySerializable(SerializableMode mode)812     public static MockitoException usingConstructorWithFancySerializable(SerializableMode mode) {
813         return new MockitoException("Mocks instantiated with constructor cannot be combined with " + mode + " serialization mode.");
814     }
815 
cannotCreateTimerWithNegativeDurationTime(long durationMillis)816     public static MockitoException cannotCreateTimerWithNegativeDurationTime(long durationMillis) {
817         return new FriendlyReminderException(join(
818                 "",
819                 "Don't panic! I'm just a friendly reminder!",
820                 "It is impossible for time to go backward, therefore...",
821                 "You cannot put negative value of duration: (" + durationMillis + ")",
822                 "as argument of timer methods (after(), timeout())",
823                 ""
824         ));
825     }
826 
notAnException()827     public static MockitoException notAnException() {
828         return new MockitoException(join(
829                 "Exception type cannot be null.",
830                 "This may happen with doThrow(Class)|thenThrow(Class) family of methods if passing null parameter."));
831     }
832 
safelyGetMockName(Object mock)833     private static MockName safelyGetMockName(Object mock) {
834         return MockUtil.getMockName(mock);
835     }
836 
formatUnncessaryStubbingException(Class<?> testClass, Collection<Invocation> unnecessaryStubbings)837     public static UnnecessaryStubbingException formatUnncessaryStubbingException(Class<?> testClass, Collection<Invocation> unnecessaryStubbings) {
838         StringBuilder stubbings = new StringBuilder();
839         int count = 1;
840         for (Invocation u : unnecessaryStubbings) {
841             stubbings.append("\n  ").append(count++).append(". ").append(u.getLocation());
842         }
843         String heading = (testClass != null)?
844                 "Unnecessary stubbings detected in test class: " + testClass.getSimpleName() :
845                 "Unnecessary stubbings detected.";
846 
847         return new UnnecessaryStubbingException(join(
848                 heading,
849                 "Clean & maintainable test code requires zero unnecessary code.",
850                 "Following stubbings are unnecessary (click to navigate to relevant line of code):" + stubbings,
851                 "Please remove unnecessary stubbings or use 'silent' option. More info: javadoc for UnnecessaryStubbingException class."
852         ));
853     }
854 
unncessaryStubbingException(List<Invocation> unused)855     public static void unncessaryStubbingException(List<Invocation> unused) {
856         throw formatUnncessaryStubbingException(null, unused);
857     }
858 
potentialStubbingProblem( Invocation actualInvocation, Collection<Invocation> argMismatchStubbings)859     public static void potentialStubbingProblem(
860             Invocation actualInvocation, Collection<Invocation> argMismatchStubbings) {
861         StringBuilder stubbings = new StringBuilder();
862         int count = 1;
863         for (Invocation s : argMismatchStubbings) {
864             stubbings.append("    ").append(count++).append(". ").append(s);
865             stubbings.append("\n      ").append(s.getLocation()).append("\n");
866         }
867         stubbings.deleteCharAt(stubbings.length()-1); //remove trailing end of line
868 
869         throw new PotentialStubbingProblem(join(
870                 "Strict stubbing argument mismatch. Please check:",
871                 " - this invocation of '" + actualInvocation.getMethod().getName() + "' method:",
872                 "    " + actualInvocation,
873                 "    " + actualInvocation.getLocation(),
874                 " - has following stubbing(s) with different arguments:",
875                 stubbings,
876                 "Typically, stubbing argument mismatch indicates user mistake when writing tests.",
877                 "Mockito fails early so that you can debug potential problem easily.",
878                 "However, there are legit scenarios when this exception generates false negative signal:",
879                 "  - stubbing the same method multiple times using 'given().will()' or 'when().then()' API",
880                 "    Please use 'will().given()' or 'doReturn().when()' API for stubbing.",
881                 "  - stubbed method is intentionally invoked with different arguments by code under test",
882                 "    Please use 'default' or 'silent' JUnit Rule.",
883                 "For more information see javadoc for PotentialStubbingProblem class."));
884     }
885 
redundantMockitoListener(String listenerType)886     public static void redundantMockitoListener(String listenerType) {
887         throw new RedundantListenerException(join(
888             "Problems adding Mockito listener.",
889             "Listener of type '" + listenerType + "' has already been added and not removed.",
890             "It indicates that previous listener was not removed according to the API.",
891             "When you add a listener, don't forget to remove the listener afterwards:",
892             "  Mockito.framework().removeListener(myListener);",
893             "For more information, see the javadoc for RedundantListenerException class."));
894     }
895 
unfinishedMockingSession()896     public static void unfinishedMockingSession() {
897         throw new UnfinishedMockingSessionException(join(
898                 "Unfinished mocking session detected.",
899                 "Previous MockitoSession was not concluded with 'finishMocking()'.",
900                 "For examples of correct usage see javadoc for MockitoSession class."));
901     }
902 }
903