AnswersValidator.java revision e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7
1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito.internal.stubbing.answers;
6
7import org.mockito.exceptions.Reporter;
8import org.mockito.invocation.Invocation;
9import org.mockito.stubbing.Answer;
10
11public class AnswersValidator {
12
13    private Reporter reporter = new Reporter();
14
15    public void validate(Answer<?> answer, Invocation invocation) {
16        MethodInfo methodInfo = new MethodInfo(invocation);
17        if (answer instanceof ThrowsException) {
18            validateException((ThrowsException) answer, methodInfo);
19        }
20
21        if (answer instanceof Returns) {
22            validateReturnValue((Returns) answer, methodInfo);
23        }
24
25        if (answer instanceof DoesNothing) {
26            validateDoNothing((DoesNothing) answer, methodInfo);
27        }
28
29        if (answer instanceof CallsRealMethods) {
30            validateMockingConcreteClass((CallsRealMethods) answer, methodInfo);
31        }
32
33        if (answer instanceof ReturnsArgumentAt) {
34            ReturnsArgumentAt returnsArgumentAt = (ReturnsArgumentAt) answer;
35            validateReturnArgIdentity(returnsArgumentAt, invocation);
36        }
37    }
38
39    private void validateReturnArgIdentity(ReturnsArgumentAt returnsArgumentAt, Invocation invocation) {
40        returnsArgumentAt.validateIndexWithinInvocationRange(invocation);
41
42        MethodInfo methodInfo = new MethodInfo(invocation);
43        if (!methodInfo.isValidReturnType(returnsArgumentAt.returnedTypeOnSignature(invocation))) {
44            new Reporter().wrongTypeOfArgumentToReturn(invocation, methodInfo.printMethodReturnType(),
45                                                       returnsArgumentAt.returnedTypeOnSignature(invocation),
46                                                       returnsArgumentAt.wantedArgumentPosition());
47        }
48
49    }
50
51    private void validateMockingConcreteClass(CallsRealMethods answer, MethodInfo methodInfo) {
52        if (methodInfo.isDeclaredOnInterface()) {
53            reporter.cannotCallRealMethodOnInterface();
54        }
55    }
56
57    private void validateDoNothing(DoesNothing answer, MethodInfo methodInfo) {
58        if (!methodInfo.isVoid()) {
59            reporter.onlyVoidMethodsCanBeSetToDoNothing();
60        }
61    }
62
63    private void validateReturnValue(Returns answer, MethodInfo methodInfo) {
64        if (methodInfo.isVoid()) {
65            reporter.cannotStubVoidMethodWithAReturnValue(methodInfo.getMethodName());
66        }
67
68        if (answer.returnsNull() && methodInfo.returnsPrimitive()) {
69            reporter.wrongTypeOfReturnValue(methodInfo.printMethodReturnType(), "null", methodInfo.getMethodName());
70        }
71
72        if (!answer.returnsNull() && !methodInfo.isValidReturnType(answer.getReturnType())) {
73            reporter.wrongTypeOfReturnValue(methodInfo.printMethodReturnType(), answer.printReturnType(), methodInfo.getMethodName());
74        }
75    }
76
77    private void validateException(ThrowsException answer, MethodInfo methodInfo) {
78        Throwable throwable = answer.getThrowable();
79        if (throwable == null) {
80            reporter.cannotStubWithNullThrowable();
81        }
82
83        if (throwable instanceof RuntimeException || throwable instanceof Error) {
84            return;
85        }
86
87        if (!methodInfo.isValidException(throwable)) {
88            reporter.checkedExceptionInvalid(throwable);
89        }
90    }
91}