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