Home | History | Annotate | Download | only in answers
      1 /*
      2  * Copyright (c) 2007 Mockito contributors
      3  * This program is made available under the terms of the MIT License.
      4  */
      5 package org.mockito.internal.stubbing.answers;
      6 
      7 import org.mockito.exceptions.Reporter;
      8 import org.mockito.invocation.Invocation;
      9 import org.mockito.stubbing.Answer;
     10 
     11 public 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 }