Home | History | Annotate | Download | only in invocation
      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.invocation;
      7 
      8 import java.lang.reflect.Method;
      9 import java.util.LinkedList;
     10 import java.util.List;
     11 import org.mockito.Mockito;
     12 import org.mockito.internal.debugging.LocationImpl;
     13 import org.mockito.internal.invocation.realmethod.RealMethod;
     14 import org.mockito.internal.util.reflection.AccessibilityChanger;
     15 import org.mockito.invocation.Invocation;
     16 import org.mockito.invocation.Location;
     17 import org.mockitousage.IMethods;
     18 
     19 import static java.util.Arrays.asList;
     20 
     21 /**
     22  * Build an invocation.
     23  */
     24 @SuppressWarnings("unchecked")
     25 public class InvocationBuilder {
     26 
     27     private String methodName = "simpleMethod";
     28     private int sequenceNumber = 0;
     29     private Object[] args = new Object[]{};
     30     private Object mock = Mockito.mock(IMethods.class);
     31     private Method method;
     32     private boolean verified;
     33     private List<Class<?>> argTypes;
     34     private Location location;
     35 
     36     /**
     37      * Build the invocation
     38      * <p>
     39      * If the method was not specified, use IMethods methods.
     40      *
     41      * @return invocation
     42      */
     43     public Invocation toInvocation() {
     44         if (method == null) {
     45             if (argTypes == null) {
     46                 argTypes = new LinkedList<Class<?>>();
     47                 for (Object arg : args) {
     48                     if (arg == null) {
     49                         argTypes.add(Object.class);
     50                     } else {
     51                         argTypes.add(arg.getClass());
     52                     }
     53                 }
     54             }
     55 
     56             try {
     57                 method = IMethods.class.getMethod(methodName, argTypes.toArray(new Class[argTypes.size()]));
     58             } catch (Exception e) {
     59                 throw new RuntimeException("builder only creates invocations of IMethods interface", e);
     60             }
     61         }
     62 
     63         Invocation i = new InvocationImpl(mock,
     64                                           new SerializableMethod(method),
     65                                           args,
     66                                           sequenceNumber,
     67                                           toDumbRealMethod(),
     68                                           location == null ? new LocationImpl() : location);
     69         if (verified) {
     70             i.markVerified();
     71         }
     72         return i;
     73     }
     74 
     75     private RealMethod toDumbRealMethod() {
     76         return new RealMethod() {
     77             @Override
     78             public Object invoke(Object target, Object[] arguments) throws Throwable {
     79                 AccessibilityChanger accessibilityChanger = new AccessibilityChanger();
     80                 try {
     81                     accessibilityChanger.enableAccess(method);
     82                     return method.invoke(target, arguments);
     83                 } finally {
     84                     accessibilityChanger.safelyDisableAccess(method);
     85                 }
     86 
     87             }
     88         };
     89     }
     90 
     91     public InvocationBuilder method(String methodName) {
     92         this.methodName = methodName;
     93         return this;
     94     }
     95 
     96     public InvocationBuilder seq(int sequenceNumber) {
     97         this.sequenceNumber = sequenceNumber;
     98         return this;
     99     }
    100 
    101     public InvocationBuilder args(Object... args) {
    102         this.args = args;
    103         return this;
    104     }
    105 
    106     public InvocationBuilder arg(Object o) {
    107         this.args = new Object[]{o};
    108         return this;
    109     }
    110 
    111     public InvocationBuilder mock(Object mock) {
    112         this.mock = mock;
    113         return this;
    114     }
    115 
    116     public InvocationBuilder method(Method method) {
    117         this.method = method;
    118         return this;
    119     }
    120 
    121     public InvocationBuilder verified() {
    122         this.verified = true;
    123         return this;
    124     }
    125 
    126     public InvocationMatcher toInvocationMatcher() {
    127         return new InvocationMatcher(toInvocation());
    128     }
    129 
    130     public InvocationBuilder simpleMethod() {
    131         return this.method("simpleMethod");
    132     }
    133 
    134     public InvocationBuilder differentMethod() {
    135         return this.method("differentMethod");
    136     }
    137 
    138     public InvocationBuilder argTypes(Class<?>... argTypes) {
    139         this.argTypes = asList(argTypes);
    140         return this;
    141     }
    142 
    143     public InvocationBuilder location(final String location) {
    144         this.location = new Location() {
    145             public String toString() {
    146                 return location;
    147             }
    148         };
    149         return this;
    150     }
    151 }
    152